xref: /petsc/src/mat/impls/dense/seq/dense.c (revision a49dc2a2a58a5a1e1e4bc7f8883a9d215246ff3f)
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
337*a49dc2a2SStefano Zampini     if (A->spd) {
3388b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
339e32f2f54SBarry Smith       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
340*a49dc2a2SStefano Zampini #if defined (PETSC_USE_COMPLEX)
341*a49dc2a2SStefano Zampini     } else if (A->hermitian) {
342*a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
343*a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
344*a49dc2a2SStefano Zampini #endif
345*a49dc2a2SStefano Zampini     } else { /* symmetric case */
346*a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
347*a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
348*a49dc2a2SStefano Zampini     }
349ae7cfcebSSatish Balay #endif
3502205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
351f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
3521ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
353dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
3543a40ed3dSBarry Smith   PetscFunctionReturn(0);
355289bc588SBarry Smith }
3566ee01492SSatish Balay 
357e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X)
35885e2c93fSHong Zhang {
35985e2c93fSHong Zhang   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
36085e2c93fSHong Zhang   PetscErrorCode ierr;
36185e2c93fSHong Zhang   PetscScalar    *b,*x;
362efb80c78SLisandro Dalcin   PetscInt       n;
363783b601eSJed Brown   PetscBLASInt   nrhs,info,m;
364bda8bf91SBarry Smith   PetscBool      flg;
36585e2c93fSHong Zhang 
36685e2c93fSHong Zhang   PetscFunctionBegin;
367c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
3680298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
369ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3700298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
371ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
372bda8bf91SBarry Smith 
3730298fd71SBarry Smith   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
374c5df96a5SBarry Smith   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
3758c778c55SBarry Smith   ierr = MatDenseGetArray(B,&b);CHKERRQ(ierr);
3768c778c55SBarry Smith   ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr);
37785e2c93fSHong Zhang 
378f272c775SHong Zhang   ierr = PetscMemcpy(x,b,m*nrhs*sizeof(PetscScalar));CHKERRQ(ierr);
37985e2c93fSHong Zhang 
38085e2c93fSHong Zhang   if (A->factortype == MAT_FACTOR_LU) {
38185e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_GETRS)
38285e2c93fSHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
38385e2c93fSHong Zhang #else
3848b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
38585e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
38685e2c93fSHong Zhang #endif
38785e2c93fSHong Zhang   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
38885e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_POTRS)
38985e2c93fSHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
39085e2c93fSHong Zhang #else
391*a49dc2a2SStefano Zampini     if (A->spd) {
3928b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
39385e2c93fSHong Zhang       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
394*a49dc2a2SStefano Zampini #if defined (PETSC_USE_COMPLEX)
395*a49dc2a2SStefano Zampini     } else if (A->hermitian) {
396*a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
397*a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
398*a49dc2a2SStefano Zampini #endif
399*a49dc2a2SStefano Zampini     } else { /* symmetric case */
400*a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
401*a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
402*a49dc2a2SStefano Zampini     }
40385e2c93fSHong Zhang #endif
4042205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
40585e2c93fSHong Zhang 
4068c778c55SBarry Smith   ierr = MatDenseRestoreArray(B,&b);CHKERRQ(ierr);
4078c778c55SBarry Smith   ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr);
40885e2c93fSHong Zhang   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
40985e2c93fSHong Zhang   PetscFunctionReturn(0);
41085e2c93fSHong Zhang }
41185e2c93fSHong Zhang 
412e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
413da3a660dSBarry Smith {
414c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
415dfbe8321SBarry Smith   PetscErrorCode    ierr;
416f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
417f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
418c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
41967e560aaSBarry Smith 
4203a40ed3dSBarry Smith   PetscFunctionBegin;
421c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
422f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4231ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
424d0f46423SBarry Smith   ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
4258208b9aeSStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
426ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
427e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
428ae7cfcebSSatish Balay #else
4298b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
430e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve");
431ae7cfcebSSatish Balay #endif
4328208b9aeSStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
433ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
434e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
435ae7cfcebSSatish Balay #else
436*a49dc2a2SStefano Zampini     if (A->spd) {
4378b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
438*a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
439*a49dc2a2SStefano Zampini #if defined (PETSC_USE_COMPLEX)
440*a49dc2a2SStefano Zampini     } else if (A->hermitian) {
441*a49dc2a2SStefano Zampini       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatSolveTranspose with Cholesky/Hermitian not available");
442ae7cfcebSSatish Balay #endif
443*a49dc2a2SStefano Zampini     } else { /* symmetric case */
444*a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
445*a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
446da3a660dSBarry Smith     }
447*a49dc2a2SStefano Zampini #endif
448*a49dc2a2SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
449f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4501ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
451dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
4523a40ed3dSBarry Smith   PetscFunctionReturn(0);
453da3a660dSBarry Smith }
4546ee01492SSatish Balay 
455e0877f53SBarry Smith static PetscErrorCode MatSolveAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
456da3a660dSBarry Smith {
457dfbe8321SBarry Smith   PetscErrorCode    ierr;
458f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
459f1ceaac6SMatthew G. Knepley   PetscScalar       *y,sone = 1.0;
460da3a660dSBarry Smith   Vec               tmp = 0;
46167e560aaSBarry Smith 
4623a40ed3dSBarry Smith   PetscFunctionBegin;
463f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4641ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
465d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
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   }
4718208b9aeSStefano Zampini   ierr = MatSolve_SeqDense(A,xx,yy);CHKERRQ(ierr);
4726bf464f9SBarry Smith   if (tmp) {
4736bf464f9SBarry Smith     ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr);
4746bf464f9SBarry Smith     ierr = VecDestroy(&tmp);CHKERRQ(ierr);
4756bf464f9SBarry Smith   } else {
4766bf464f9SBarry Smith     ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr);
4776bf464f9SBarry Smith   }
478f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4791ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
4808208b9aeSStefano Zampini   ierr = PetscLogFlops(A->cmap->n);CHKERRQ(ierr);
4813a40ed3dSBarry Smith   PetscFunctionReturn(0);
482da3a660dSBarry Smith }
48367e560aaSBarry Smith 
484e0877f53SBarry Smith static PetscErrorCode MatSolveTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
485da3a660dSBarry Smith {
4866849ba73SBarry Smith   PetscErrorCode    ierr;
487f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
488f1ceaac6SMatthew G. Knepley   PetscScalar       *y,sone = 1.0;
48989ae1891SBarry Smith   Vec               tmp = NULL;
49067e560aaSBarry Smith 
4913a40ed3dSBarry Smith   PetscFunctionBegin;
492d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
493f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4941ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
495da3a660dSBarry Smith   if (yy == zz) {
49678b31e54SBarry Smith     ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr);
4973bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)tmp);CHKERRQ(ierr);
49878b31e54SBarry Smith     ierr = VecCopy(yy,tmp);CHKERRQ(ierr);
499da3a660dSBarry Smith   }
5008208b9aeSStefano Zampini   ierr = MatSolveTranspose_SeqDense(A,xx,yy);CHKERRQ(ierr);
50190f02eecSBarry Smith   if (tmp) {
5022dcb1b2aSMatthew Knepley     ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr);
5036bf464f9SBarry Smith     ierr = VecDestroy(&tmp);CHKERRQ(ierr);
5043a40ed3dSBarry Smith   } else {
5052dcb1b2aSMatthew Knepley     ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr);
50690f02eecSBarry Smith   }
507f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5081ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
5098208b9aeSStefano Zampini   ierr = PetscLogFlops(A->cmap->n);CHKERRQ(ierr);
5103a40ed3dSBarry Smith   PetscFunctionReturn(0);
511da3a660dSBarry Smith }
512db4efbfdSBarry Smith 
513db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
514db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
515db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
516e0877f53SBarry Smith static PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
517db4efbfdSBarry Smith {
518db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_GETRF)
519db4efbfdSBarry Smith   PetscFunctionBegin;
520e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRF - Lapack routine is unavailable.");
521db4efbfdSBarry Smith #else
522db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
523db4efbfdSBarry Smith   PetscErrorCode ierr;
524db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
525db4efbfdSBarry Smith 
526db4efbfdSBarry Smith   PetscFunctionBegin;
527c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
528c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
529db4efbfdSBarry Smith   if (!mat->pivots) {
5308208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
5313bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
532db4efbfdSBarry Smith   }
533db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
5348e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5358b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
5368e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
5378e57ea43SSatish Balay 
538e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
539e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
5408208b9aeSStefano Zampini 
541db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
5428208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
543db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
544db4efbfdSBarry Smith   A->ops->solveadd          = MatSolveAdd_SeqDense;
545db4efbfdSBarry Smith   A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
546d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
547db4efbfdSBarry Smith 
548f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
549f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
550f6224b95SHong Zhang 
551dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
552db4efbfdSBarry Smith #endif
553db4efbfdSBarry Smith   PetscFunctionReturn(0);
554db4efbfdSBarry Smith }
555db4efbfdSBarry Smith 
556*a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
557e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
558db4efbfdSBarry Smith {
559db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_POTRF)
560db4efbfdSBarry Smith   PetscFunctionBegin;
561e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF - Lapack routine is unavailable.");
562db4efbfdSBarry Smith #else
563db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
564db4efbfdSBarry Smith   PetscErrorCode ierr;
565c5df96a5SBarry Smith   PetscBLASInt   info,n;
566db4efbfdSBarry Smith 
567db4efbfdSBarry Smith   PetscFunctionBegin;
568c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
569db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
570*a49dc2a2SStefano Zampini   if (A->spd) {
5718b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
572*a49dc2a2SStefano Zampini #if defined (PETSC_USE_COMPLEX)
573*a49dc2a2SStefano Zampini   } else if (A->hermitian) {
574*a49dc2a2SStefano Zampini     if (!mat->pivots) {
575*a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
576*a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
577*a49dc2a2SStefano Zampini     }
578*a49dc2a2SStefano Zampini     if (!mat->fwork) {
579*a49dc2a2SStefano Zampini       PetscScalar dummy;
580*a49dc2a2SStefano Zampini 
581*a49dc2a2SStefano Zampini       mat->lfwork = -1;
582*a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
583*a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
584*a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
585*a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
586*a49dc2a2SStefano Zampini     }
587*a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
588*a49dc2a2SStefano Zampini #endif
589*a49dc2a2SStefano Zampini   } else { /* symmetric case */
590*a49dc2a2SStefano Zampini     if (!mat->pivots) {
591*a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
592*a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
593*a49dc2a2SStefano Zampini     }
594*a49dc2a2SStefano Zampini     if (!mat->fwork) {
595*a49dc2a2SStefano Zampini       PetscScalar dummy;
596*a49dc2a2SStefano Zampini 
597*a49dc2a2SStefano Zampini       mat->lfwork = -1;
598*a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
599*a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
600*a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
601*a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
602*a49dc2a2SStefano Zampini     }
603*a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
604*a49dc2a2SStefano Zampini   }
605e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
6068208b9aeSStefano Zampini 
607db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6088208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
609db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
610db4efbfdSBarry Smith   A->ops->solveadd          = MatSolveAdd_SeqDense;
611db4efbfdSBarry Smith   A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
612d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
6132205254eSKarl Rupp 
614f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
615f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
616f6224b95SHong Zhang 
617eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
618db4efbfdSBarry Smith #endif
619db4efbfdSBarry Smith   PetscFunctionReturn(0);
620db4efbfdSBarry Smith }
621db4efbfdSBarry Smith 
622db4efbfdSBarry Smith 
6230481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
624db4efbfdSBarry Smith {
625db4efbfdSBarry Smith   PetscErrorCode ierr;
626db4efbfdSBarry Smith   MatFactorInfo  info;
627db4efbfdSBarry Smith 
628db4efbfdSBarry Smith   PetscFunctionBegin;
629db4efbfdSBarry Smith   info.fill = 1.0;
6302205254eSKarl Rupp 
631c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
632719d5645SBarry Smith   ierr = MatCholeskyFactor_SeqDense(fact,0,&info);CHKERRQ(ierr);
633db4efbfdSBarry Smith   PetscFunctionReturn(0);
634db4efbfdSBarry Smith }
635db4efbfdSBarry Smith 
636e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
637db4efbfdSBarry Smith {
638db4efbfdSBarry Smith   PetscFunctionBegin;
639c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
6401bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
641719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
642db4efbfdSBarry Smith   PetscFunctionReturn(0);
643db4efbfdSBarry Smith }
644db4efbfdSBarry Smith 
645e0877f53SBarry Smith static PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
646db4efbfdSBarry Smith {
647db4efbfdSBarry Smith   PetscFunctionBegin;
648b66fe19dSMatthew G Knepley   fact->preallocated         = PETSC_TRUE;
649c3ef05f6SHong Zhang   fact->assembled            = PETSC_TRUE;
650719d5645SBarry Smith   fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense;
651db4efbfdSBarry Smith   PetscFunctionReturn(0);
652db4efbfdSBarry Smith }
653db4efbfdSBarry Smith 
654cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
655db4efbfdSBarry Smith {
656db4efbfdSBarry Smith   PetscErrorCode ierr;
657db4efbfdSBarry Smith 
658db4efbfdSBarry Smith   PetscFunctionBegin;
659ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
660db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
661db4efbfdSBarry Smith   ierr = MatSetType(*fact,((PetscObject)A)->type_name);CHKERRQ(ierr);
662db4efbfdSBarry Smith   if (ftype == MAT_FACTOR_LU) {
663db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
664db4efbfdSBarry Smith   } else {
665db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
666db4efbfdSBarry Smith   }
667d5f3da31SBarry Smith   (*fact)->factortype = ftype;
66800c67f3bSHong Zhang 
66900c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
67000c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
671db4efbfdSBarry Smith   PetscFunctionReturn(0);
672db4efbfdSBarry Smith }
673db4efbfdSBarry Smith 
674289bc588SBarry Smith /* ------------------------------------------------------------------*/
675e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
676289bc588SBarry Smith {
677c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
678d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
679d9ca1df4SBarry Smith   const PetscScalar *b;
680dfbe8321SBarry Smith   PetscErrorCode    ierr;
681d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
682c5df96a5SBarry Smith   PetscBLASInt      o = 1,bm;
683289bc588SBarry Smith 
6843a40ed3dSBarry Smith   PetscFunctionBegin;
685422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
686c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
687289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
68871044d3cSBarry Smith     /* this is a hack fix, should have another version without the second BLASdot */
6892dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
690289bc588SBarry Smith   }
6911ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
692d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
693b965ef7fSBarry Smith   its  = its*lits;
694e32f2f54SBarry 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);
695289bc588SBarry Smith   while (its--) {
696fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
697289bc588SBarry Smith       for (i=0; i<m; i++) {
6988b83055fSJed Brown         PetscStackCallBLAS("BLASdot",xt   = b[i] - BLASdot_(&bm,v+i,&bm,x,&o));
69955a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
700289bc588SBarry Smith       }
701289bc588SBarry Smith     }
702fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
703289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
7048b83055fSJed Brown         PetscStackCallBLAS("BLASdot",xt   = b[i] - BLASdot_(&bm,v+i,&bm,x,&o));
70555a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
706289bc588SBarry Smith       }
707289bc588SBarry Smith     }
708289bc588SBarry Smith   }
709d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
7101ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
7113a40ed3dSBarry Smith   PetscFunctionReturn(0);
712289bc588SBarry Smith }
713289bc588SBarry Smith 
714289bc588SBarry Smith /* -----------------------------------------------------------------*/
715cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
716289bc588SBarry Smith {
717c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
718d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
719d9ca1df4SBarry Smith   PetscScalar       *y;
720dfbe8321SBarry Smith   PetscErrorCode    ierr;
7210805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
722ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
7233a40ed3dSBarry Smith 
7243a40ed3dSBarry Smith   PetscFunctionBegin;
725c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
726c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
727d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
728d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
7291ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
7308b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
731d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
7321ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
733dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
7343a40ed3dSBarry Smith   PetscFunctionReturn(0);
735289bc588SBarry Smith }
736800995b7SMatthew Knepley 
737cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
738289bc588SBarry Smith {
739c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
740d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
741dfbe8321SBarry Smith   PetscErrorCode    ierr;
7420805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
743d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
7443a40ed3dSBarry Smith 
7453a40ed3dSBarry Smith   PetscFunctionBegin;
746c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
747c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
748d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
749d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
7501ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
7518b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
752d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
7531ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
754dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
7553a40ed3dSBarry Smith   PetscFunctionReturn(0);
756289bc588SBarry Smith }
7576ee01492SSatish Balay 
758cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
759289bc588SBarry Smith {
760c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
761d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
762d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
763dfbe8321SBarry Smith   PetscErrorCode    ierr;
7640805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
7653a40ed3dSBarry Smith 
7663a40ed3dSBarry Smith   PetscFunctionBegin;
767c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
768c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
769d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
770600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
771d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
7721ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
7738b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
774d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
7751ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
776dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
7773a40ed3dSBarry Smith   PetscFunctionReturn(0);
778289bc588SBarry Smith }
7796ee01492SSatish Balay 
780e0877f53SBarry Smith static PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
781289bc588SBarry Smith {
782c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
783d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
784d9ca1df4SBarry Smith   PetscScalar       *y;
785dfbe8321SBarry Smith   PetscErrorCode    ierr;
7860805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
78787828ca2SBarry Smith   PetscScalar       _DOne=1.0;
7883a40ed3dSBarry Smith 
7893a40ed3dSBarry Smith   PetscFunctionBegin;
790c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
791c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
792d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
793600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
794d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
7951ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
7968b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
797d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
7981ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
799dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8003a40ed3dSBarry Smith   PetscFunctionReturn(0);
801289bc588SBarry Smith }
802289bc588SBarry Smith 
803289bc588SBarry Smith /* -----------------------------------------------------------------*/
804e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
805289bc588SBarry Smith {
806c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
80787828ca2SBarry Smith   PetscScalar    *v;
8086849ba73SBarry Smith   PetscErrorCode ierr;
80913f74950SBarry Smith   PetscInt       i;
81067e560aaSBarry Smith 
8113a40ed3dSBarry Smith   PetscFunctionBegin;
812d0f46423SBarry Smith   *ncols = A->cmap->n;
813289bc588SBarry Smith   if (cols) {
814854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
815d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
816289bc588SBarry Smith   }
817289bc588SBarry Smith   if (vals) {
818854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
819289bc588SBarry Smith     v    = mat->v + row;
820d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
821289bc588SBarry Smith   }
8223a40ed3dSBarry Smith   PetscFunctionReturn(0);
823289bc588SBarry Smith }
8246ee01492SSatish Balay 
825e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
826289bc588SBarry Smith {
827dfbe8321SBarry Smith   PetscErrorCode ierr;
8286e111a19SKarl Rupp 
829606d414cSSatish Balay   PetscFunctionBegin;
830606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
831606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
8323a40ed3dSBarry Smith   PetscFunctionReturn(0);
833289bc588SBarry Smith }
834289bc588SBarry Smith /* ----------------------------------------------------------------*/
835e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
836289bc588SBarry Smith {
837c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
83813f74950SBarry Smith   PetscInt     i,j,idx=0;
839d6dfbf8fSBarry Smith 
8403a40ed3dSBarry Smith   PetscFunctionBegin;
841289bc588SBarry Smith   if (!mat->roworiented) {
842dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
843289bc588SBarry Smith       for (j=0; j<n; j++) {
844cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
8452515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
846e32f2f54SBarry 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);
84758804f6dSBarry Smith #endif
848289bc588SBarry Smith         for (i=0; i<m; i++) {
849cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
8502515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
851e32f2f54SBarry 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);
85258804f6dSBarry Smith #endif
853cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
854289bc588SBarry Smith         }
855289bc588SBarry Smith       }
8563a40ed3dSBarry Smith     } else {
857289bc588SBarry Smith       for (j=0; j<n; j++) {
858cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
8592515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
860e32f2f54SBarry 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);
86158804f6dSBarry Smith #endif
862289bc588SBarry Smith         for (i=0; i<m; i++) {
863cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
8642515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
865e32f2f54SBarry 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);
86658804f6dSBarry Smith #endif
867cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
868289bc588SBarry Smith         }
869289bc588SBarry Smith       }
870289bc588SBarry Smith     }
8713a40ed3dSBarry Smith   } else {
872dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
873e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
874cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
8752515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
876e32f2f54SBarry 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);
87758804f6dSBarry Smith #endif
878e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
879cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
8802515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
881e32f2f54SBarry 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);
88258804f6dSBarry Smith #endif
883cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
884e8d4e0b9SBarry Smith         }
885e8d4e0b9SBarry Smith       }
8863a40ed3dSBarry Smith     } else {
887289bc588SBarry Smith       for (i=0; i<m; i++) {
888cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
8892515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
890e32f2f54SBarry 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);
89158804f6dSBarry Smith #endif
892289bc588SBarry Smith         for (j=0; j<n; j++) {
893cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
8942515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
895e32f2f54SBarry 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);
89658804f6dSBarry Smith #endif
897cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
898289bc588SBarry Smith         }
899289bc588SBarry Smith       }
900289bc588SBarry Smith     }
901e8d4e0b9SBarry Smith   }
9023a40ed3dSBarry Smith   PetscFunctionReturn(0);
903289bc588SBarry Smith }
904e8d4e0b9SBarry Smith 
905e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
906ae80bb75SLois Curfman McInnes {
907ae80bb75SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
90813f74950SBarry Smith   PetscInt     i,j;
909ae80bb75SLois Curfman McInnes 
9103a40ed3dSBarry Smith   PetscFunctionBegin;
911ae80bb75SLois Curfman McInnes   /* row-oriented output */
912ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
91397e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
914e32f2f54SBarry 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);
915ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
9166f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
917e32f2f54SBarry 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);
91897e567efSBarry Smith       *v++ = mat->v[indexn[j]*mat->lda + indexm[i]];
919ae80bb75SLois Curfman McInnes     }
920ae80bb75SLois Curfman McInnes   }
9213a40ed3dSBarry Smith   PetscFunctionReturn(0);
922ae80bb75SLois Curfman McInnes }
923ae80bb75SLois Curfman McInnes 
924289bc588SBarry Smith /* -----------------------------------------------------------------*/
925289bc588SBarry Smith 
926e0877f53SBarry Smith static PetscErrorCode MatLoad_SeqDense(Mat newmat,PetscViewer viewer)
927aabbc4fbSShri Abhyankar {
928aabbc4fbSShri Abhyankar   Mat_SeqDense   *a;
929aabbc4fbSShri Abhyankar   PetscErrorCode ierr;
930aabbc4fbSShri Abhyankar   PetscInt       *scols,i,j,nz,header[4];
931aabbc4fbSShri Abhyankar   int            fd;
932aabbc4fbSShri Abhyankar   PetscMPIInt    size;
933aabbc4fbSShri Abhyankar   PetscInt       *rowlengths = 0,M,N,*cols,grows,gcols;
934aabbc4fbSShri Abhyankar   PetscScalar    *vals,*svals,*v,*w;
935ce94432eSBarry Smith   MPI_Comm       comm;
936aabbc4fbSShri Abhyankar 
937aabbc4fbSShri Abhyankar   PetscFunctionBegin;
938c98fd787SBarry Smith   /* force binary viewer to load .info file if it has not yet done so */
939c98fd787SBarry Smith   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
940ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
941aabbc4fbSShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
942aabbc4fbSShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"view must have one processor");
943aabbc4fbSShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
944aabbc4fbSShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
945aabbc4fbSShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not matrix object");
946aabbc4fbSShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
947aabbc4fbSShri Abhyankar 
948aabbc4fbSShri Abhyankar   /* set global size if not set already*/
949aabbc4fbSShri Abhyankar   if (newmat->rmap->n < 0 && newmat->rmap->N < 0 && newmat->cmap->n < 0 && newmat->cmap->N < 0) {
950aabbc4fbSShri Abhyankar     ierr = MatSetSizes(newmat,M,N,M,N);CHKERRQ(ierr);
951aabbc4fbSShri Abhyankar   } else {
952aabbc4fbSShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
953aabbc4fbSShri Abhyankar     ierr = MatGetSize(newmat,&grows,&gcols);CHKERRQ(ierr);
954aabbc4fbSShri 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);
955aabbc4fbSShri Abhyankar   }
956e6324fbbSBarry Smith   a = (Mat_SeqDense*)newmat->data;
957e6324fbbSBarry Smith   if (!a->user_alloc) {
9580298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
959e6324fbbSBarry Smith   }
960aabbc4fbSShri Abhyankar 
961aabbc4fbSShri Abhyankar   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense */
962aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
963aabbc4fbSShri Abhyankar     v = a->v;
964aabbc4fbSShri Abhyankar     /* Allocate some temp space to read in the values and then flip them
965aabbc4fbSShri Abhyankar        from row major to column major */
966854ce69bSBarry Smith     ierr = PetscMalloc1(M*N > 0 ? M*N : 1,&w);CHKERRQ(ierr);
967aabbc4fbSShri Abhyankar     /* read in nonzero values */
968aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,w,M*N,PETSC_SCALAR);CHKERRQ(ierr);
969aabbc4fbSShri Abhyankar     /* now flip the values and store them in the matrix*/
970aabbc4fbSShri Abhyankar     for (j=0; j<N; j++) {
971aabbc4fbSShri Abhyankar       for (i=0; i<M; i++) {
972aabbc4fbSShri Abhyankar         *v++ =w[i*N+j];
973aabbc4fbSShri Abhyankar       }
974aabbc4fbSShri Abhyankar     }
975aabbc4fbSShri Abhyankar     ierr = PetscFree(w);CHKERRQ(ierr);
976aabbc4fbSShri Abhyankar   } else {
977aabbc4fbSShri Abhyankar     /* read row lengths */
978854ce69bSBarry Smith     ierr = PetscMalloc1(M+1,&rowlengths);CHKERRQ(ierr);
979aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
980aabbc4fbSShri Abhyankar 
981aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
982aabbc4fbSShri Abhyankar     v = a->v;
983aabbc4fbSShri Abhyankar 
984aabbc4fbSShri Abhyankar     /* read column indices and nonzeros */
985854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&scols);CHKERRQ(ierr);
986aabbc4fbSShri Abhyankar     cols = scols;
987aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT);CHKERRQ(ierr);
988854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&svals);CHKERRQ(ierr);
989aabbc4fbSShri Abhyankar     vals = svals;
990aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR);CHKERRQ(ierr);
991aabbc4fbSShri Abhyankar 
992aabbc4fbSShri Abhyankar     /* insert into matrix */
993aabbc4fbSShri Abhyankar     for (i=0; i<M; i++) {
994aabbc4fbSShri Abhyankar       for (j=0; j<rowlengths[i]; j++) v[i+M*scols[j]] = svals[j];
995aabbc4fbSShri Abhyankar       svals += rowlengths[i]; scols += rowlengths[i];
996aabbc4fbSShri Abhyankar     }
997aabbc4fbSShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
998aabbc4fbSShri Abhyankar     ierr = PetscFree(cols);CHKERRQ(ierr);
999aabbc4fbSShri Abhyankar     ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1000aabbc4fbSShri Abhyankar   }
1001aabbc4fbSShri Abhyankar   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1002aabbc4fbSShri Abhyankar   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1003aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1004aabbc4fbSShri Abhyankar }
1005aabbc4fbSShri Abhyankar 
10066849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1007289bc588SBarry Smith {
1008932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1009dfbe8321SBarry Smith   PetscErrorCode    ierr;
101013f74950SBarry Smith   PetscInt          i,j;
10112dcb1b2aSMatthew Knepley   const char        *name;
101287828ca2SBarry Smith   PetscScalar       *v;
1013f3ef73ceSBarry Smith   PetscViewerFormat format;
10145f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1015ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
10165f481a85SSatish Balay #endif
1017932b0c3eSLois Curfman McInnes 
10183a40ed3dSBarry Smith   PetscFunctionBegin;
1019b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1020456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
10213a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1022fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1023d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1024d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
102544cd7ae7SLois Curfman McInnes       v    = a->v + i;
102677431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1027d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1028aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1029329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
103057622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1031329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
103257622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
10336831982aSBarry Smith         }
103480cd9d93SLois Curfman McInnes #else
10356831982aSBarry Smith         if (*v) {
103657622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
10376831982aSBarry Smith         }
103880cd9d93SLois Curfman McInnes #endif
10391b807ce4Svictorle         v += a->lda;
104080cd9d93SLois Curfman McInnes       }
1041b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
104280cd9d93SLois Curfman McInnes     }
1043d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
10443a40ed3dSBarry Smith   } else {
1045d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1046aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
104747989497SBarry Smith     /* determine if matrix has all real values */
104847989497SBarry Smith     v = a->v;
1049d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1050ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
105147989497SBarry Smith     }
105247989497SBarry Smith #endif
1053fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
10543a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1055d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1056d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1057fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1058ffac6cdbSBarry Smith     }
1059ffac6cdbSBarry Smith 
1060d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1061932b0c3eSLois Curfman McInnes       v = a->v + i;
1062d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1063aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
106447989497SBarry Smith         if (allreal) {
1065c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
106647989497SBarry Smith         } else {
1067c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
106847989497SBarry Smith         }
1069289bc588SBarry Smith #else
1070c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1071289bc588SBarry Smith #endif
10721b807ce4Svictorle         v += a->lda;
1073289bc588SBarry Smith       }
1074b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1075289bc588SBarry Smith     }
1076fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1077b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1078ffac6cdbSBarry Smith     }
1079d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1080da3a660dSBarry Smith   }
1081b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
10823a40ed3dSBarry Smith   PetscFunctionReturn(0);
1083289bc588SBarry Smith }
1084289bc588SBarry Smith 
10856849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_Binary(Mat A,PetscViewer viewer)
1086932b0c3eSLois Curfman McInnes {
1087932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
10886849ba73SBarry Smith   PetscErrorCode    ierr;
108913f74950SBarry Smith   int               fd;
1090d0f46423SBarry Smith   PetscInt          ict,j,n = A->cmap->n,m = A->rmap->n,i,*col_lens,nz = m*n;
1091f4403165SShri Abhyankar   PetscScalar       *v,*anonz,*vals;
1092f4403165SShri Abhyankar   PetscViewerFormat format;
1093932b0c3eSLois Curfman McInnes 
10943a40ed3dSBarry Smith   PetscFunctionBegin;
1095b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
109690ace30eSBarry Smith 
1097f4403165SShri Abhyankar   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1098f4403165SShri Abhyankar   if (format == PETSC_VIEWER_NATIVE) {
1099f4403165SShri Abhyankar     /* store the matrix as a dense matrix */
1100785e854fSJed Brown     ierr = PetscMalloc1(4,&col_lens);CHKERRQ(ierr);
11012205254eSKarl Rupp 
1102f4403165SShri Abhyankar     col_lens[0] = MAT_FILE_CLASSID;
1103f4403165SShri Abhyankar     col_lens[1] = m;
1104f4403165SShri Abhyankar     col_lens[2] = n;
1105f4403165SShri Abhyankar     col_lens[3] = MATRIX_BINARY_FORMAT_DENSE;
11062205254eSKarl Rupp 
1107f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,col_lens,4,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1108f4403165SShri Abhyankar     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1109f4403165SShri Abhyankar 
1110f4403165SShri Abhyankar     /* write out matrix, by rows */
1111854ce69bSBarry Smith     ierr = PetscMalloc1(m*n+1,&vals);CHKERRQ(ierr);
1112f4403165SShri Abhyankar     v    = a->v;
1113f4403165SShri Abhyankar     for (j=0; j<n; j++) {
1114f4403165SShri Abhyankar       for (i=0; i<m; i++) {
1115f4403165SShri Abhyankar         vals[j + i*n] = *v++;
1116f4403165SShri Abhyankar       }
1117f4403165SShri Abhyankar     }
1118f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,vals,n*m,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1119f4403165SShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1120f4403165SShri Abhyankar   } else {
1121854ce69bSBarry Smith     ierr = PetscMalloc1(4+nz,&col_lens);CHKERRQ(ierr);
11222205254eSKarl Rupp 
11230700a824SBarry Smith     col_lens[0] = MAT_FILE_CLASSID;
1124932b0c3eSLois Curfman McInnes     col_lens[1] = m;
1125932b0c3eSLois Curfman McInnes     col_lens[2] = n;
1126932b0c3eSLois Curfman McInnes     col_lens[3] = nz;
1127932b0c3eSLois Curfman McInnes 
1128932b0c3eSLois Curfman McInnes     /* store lengths of each row and write (including header) to file */
1129932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) col_lens[4+i] = n;
11306f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,4+m,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1131932b0c3eSLois Curfman McInnes 
1132932b0c3eSLois Curfman McInnes     /* Possibly should write in smaller increments, not whole matrix at once? */
1133932b0c3eSLois Curfman McInnes     /* store column indices (zero start index) */
1134932b0c3eSLois Curfman McInnes     ict = 0;
1135932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1136932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) col_lens[ict++] = j;
1137932b0c3eSLois Curfman McInnes     }
11386f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
1139606d414cSSatish Balay     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1140932b0c3eSLois Curfman McInnes 
1141932b0c3eSLois Curfman McInnes     /* store nonzero values */
1142854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&anonz);CHKERRQ(ierr);
1143932b0c3eSLois Curfman McInnes     ict  = 0;
1144932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1145932b0c3eSLois Curfman McInnes       v = a->v + i;
1146932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) {
11471b807ce4Svictorle         anonz[ict++] = *v; v += a->lda;
1148932b0c3eSLois Curfman McInnes       }
1149932b0c3eSLois Curfman McInnes     }
11506f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,anonz,nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1151606d414cSSatish Balay     ierr = PetscFree(anonz);CHKERRQ(ierr);
1152f4403165SShri Abhyankar   }
11533a40ed3dSBarry Smith   PetscFunctionReturn(0);
1154932b0c3eSLois Curfman McInnes }
1155932b0c3eSLois Curfman McInnes 
11569804daf3SBarry Smith #include <petscdraw.h>
1157e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1158f1af5d2fSBarry Smith {
1159f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
1160f1af5d2fSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
11616849ba73SBarry Smith   PetscErrorCode    ierr;
1162383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1163383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
116487828ca2SBarry Smith   PetscScalar       *v = a->v;
1165b0a32e0cSBarry Smith   PetscViewer       viewer;
1166b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1167f3ef73ceSBarry Smith   PetscViewerFormat format;
1168f1af5d2fSBarry Smith 
1169f1af5d2fSBarry Smith   PetscFunctionBegin;
1170f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1171b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1172b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1173f1af5d2fSBarry Smith 
1174f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1175383922c3SLisandro Dalcin 
1176fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1177383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1178f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1179f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1180383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1181f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1182f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1183f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1184329f5518SBarry Smith         if (PetscRealPart(v[j*m+i]) >  0.) {
1185b0a32e0cSBarry Smith           color = PETSC_DRAW_RED;
1186329f5518SBarry Smith         } else if (PetscRealPart(v[j*m+i]) <  0.) {
1187b0a32e0cSBarry Smith           color = PETSC_DRAW_BLUE;
1188f1af5d2fSBarry Smith         } else {
1189f1af5d2fSBarry Smith           continue;
1190f1af5d2fSBarry Smith         }
1191b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1192f1af5d2fSBarry Smith       }
1193f1af5d2fSBarry Smith     }
1194383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1195f1af5d2fSBarry Smith   } else {
1196f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1197f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1198b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1199b05fc000SLisandro Dalcin     PetscDraw popup;
1200b05fc000SLisandro Dalcin 
1201f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1202f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1203f1af5d2fSBarry Smith     }
1204383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1205b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
120645f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1207383922c3SLisandro Dalcin 
1208383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1209f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1210f1af5d2fSBarry Smith       x_l = j;
1211f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1212f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1213f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1214f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1215b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1216b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1217f1af5d2fSBarry Smith       }
1218f1af5d2fSBarry Smith     }
1219383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1220f1af5d2fSBarry Smith   }
1221f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1222f1af5d2fSBarry Smith }
1223f1af5d2fSBarry Smith 
1224e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1225f1af5d2fSBarry Smith {
1226b0a32e0cSBarry Smith   PetscDraw      draw;
1227ace3abfcSBarry Smith   PetscBool      isnull;
1228329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1229dfbe8321SBarry Smith   PetscErrorCode ierr;
1230f1af5d2fSBarry Smith 
1231f1af5d2fSBarry Smith   PetscFunctionBegin;
1232b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1233b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1234abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1235f1af5d2fSBarry Smith 
1236d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1237f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1238b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1239832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1240b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
12410298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1242832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1243f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1244f1af5d2fSBarry Smith }
1245f1af5d2fSBarry Smith 
1246dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1247932b0c3eSLois Curfman McInnes {
1248dfbe8321SBarry Smith   PetscErrorCode ierr;
1249ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1250932b0c3eSLois Curfman McInnes 
12513a40ed3dSBarry Smith   PetscFunctionBegin;
1252251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1253251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1254251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
12550f5bd95cSBarry Smith 
1256c45a1595SBarry Smith   if (iascii) {
1257c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
12580f5bd95cSBarry Smith   } else if (isbinary) {
12593a40ed3dSBarry Smith     ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr);
1260f1af5d2fSBarry Smith   } else if (isdraw) {
1261f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1262932b0c3eSLois Curfman McInnes   }
12633a40ed3dSBarry Smith   PetscFunctionReturn(0);
1264932b0c3eSLois Curfman McInnes }
1265289bc588SBarry Smith 
1266e0877f53SBarry Smith static PetscErrorCode MatDestroy_SeqDense(Mat mat)
1267289bc588SBarry Smith {
1268ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1269dfbe8321SBarry Smith   PetscErrorCode ierr;
127090f02eecSBarry Smith 
12713a40ed3dSBarry Smith   PetscFunctionBegin;
1272aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1273d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1274a5a9c739SBarry Smith #endif
127505b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1276*a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1277abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
12786857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1279bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1280dbd8c25aSHong Zhang 
1281dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
1282bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
1283bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
12848baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
12858baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
12868baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
12878baccfbdSHong Zhang #endif
1288bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
1289bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1290bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1291bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1292abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatPtAP_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
12933bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
12943bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
12953bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
12963a40ed3dSBarry Smith   PetscFunctionReturn(0);
1297289bc588SBarry Smith }
1298289bc588SBarry Smith 
1299e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1300289bc588SBarry Smith {
1301c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
13026849ba73SBarry Smith   PetscErrorCode ierr;
130313f74950SBarry Smith   PetscInt       k,j,m,n,M;
130487828ca2SBarry Smith   PetscScalar    *v,tmp;
130548b35521SBarry Smith 
13063a40ed3dSBarry Smith   PetscFunctionBegin;
1307d0f46423SBarry Smith   v = mat->v; m = A->rmap->n; M = mat->lda; n = A->cmap->n;
1308cf37664fSBarry Smith   if (reuse == MAT_INPLACE_MATRIX) { /* in place transpose */
1309e7e72b3dSBarry Smith     if (m != n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can not transpose non-square matrix in place");
1310e7e72b3dSBarry Smith     else {
1311d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1312289bc588SBarry Smith         for (k=0; k<j; k++) {
13131b807ce4Svictorle           tmp        = v[j + k*M];
13141b807ce4Svictorle           v[j + k*M] = v[k + j*M];
13151b807ce4Svictorle           v[k + j*M] = tmp;
1316289bc588SBarry Smith         }
1317289bc588SBarry Smith       }
1318d64ed03dSBarry Smith     }
13193a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1320d3e5ee88SLois Curfman McInnes     Mat          tmat;
1321ec8511deSBarry Smith     Mat_SeqDense *tmatd;
132287828ca2SBarry Smith     PetscScalar  *v2;
1323af36a384SStefano Zampini     PetscInt     M2;
1324ea709b57SSatish Balay 
1325fc4dec0aSBarry Smith     if (reuse == MAT_INITIAL_MATRIX) {
1326ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1327d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
13287adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
13290298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1330fc4dec0aSBarry Smith     } else {
1331fc4dec0aSBarry Smith       tmat = *matout;
1332fc4dec0aSBarry Smith     }
1333ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1334af36a384SStefano Zampini     v = mat->v; v2 = tmatd->v; M2 = tmatd->lda;
1335d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1336af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1337d3e5ee88SLois Curfman McInnes     }
13386d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
13396d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1340d3e5ee88SLois Curfman McInnes     *matout = tmat;
134148b35521SBarry Smith   }
13423a40ed3dSBarry Smith   PetscFunctionReturn(0);
1343289bc588SBarry Smith }
1344289bc588SBarry Smith 
1345e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1346289bc588SBarry Smith {
1347c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat1 = (Mat_SeqDense*)A1->data;
1348c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat2 = (Mat_SeqDense*)A2->data;
134913f74950SBarry Smith   PetscInt     i,j;
1350a2ea699eSBarry Smith   PetscScalar  *v1,*v2;
13519ea5d5aeSSatish Balay 
13523a40ed3dSBarry Smith   PetscFunctionBegin;
1353d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1354d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1355d0f46423SBarry Smith   for (i=0; i<A1->rmap->n; i++) {
13561b807ce4Svictorle     v1 = mat1->v+i; v2 = mat2->v+i;
1357d0f46423SBarry Smith     for (j=0; j<A1->cmap->n; j++) {
13583a40ed3dSBarry Smith       if (*v1 != *v2) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
13591b807ce4Svictorle       v1 += mat1->lda; v2 += mat2->lda;
13601b807ce4Svictorle     }
1361289bc588SBarry Smith   }
136277c4ece6SBarry Smith   *flg = PETSC_TRUE;
13633a40ed3dSBarry Smith   PetscFunctionReturn(0);
1364289bc588SBarry Smith }
1365289bc588SBarry Smith 
1366e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1367289bc588SBarry Smith {
1368c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
1369dfbe8321SBarry Smith   PetscErrorCode ierr;
137013f74950SBarry Smith   PetscInt       i,n,len;
137187828ca2SBarry Smith   PetscScalar    *x,zero = 0.0;
137244cd7ae7SLois Curfman McInnes 
13733a40ed3dSBarry Smith   PetscFunctionBegin;
13742dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
13757a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
13761ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1377d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1378e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
137944cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
13801b807ce4Svictorle     x[i] = mat->v[i*mat->lda + i];
1381289bc588SBarry Smith   }
13821ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
13833a40ed3dSBarry Smith   PetscFunctionReturn(0);
1384289bc588SBarry Smith }
1385289bc588SBarry Smith 
1386e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1387289bc588SBarry Smith {
1388c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1389f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1390f1ceaac6SMatthew G. Knepley   PetscScalar       x,*v;
1391dfbe8321SBarry Smith   PetscErrorCode    ierr;
1392d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
139355659b69SBarry Smith 
13943a40ed3dSBarry Smith   PetscFunctionBegin;
139528988994SBarry Smith   if (ll) {
13967a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1397f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1398e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1399da3a660dSBarry Smith     for (i=0; i<m; i++) {
1400da3a660dSBarry Smith       x = l[i];
1401da3a660dSBarry Smith       v = mat->v + i;
1402b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1403da3a660dSBarry Smith     }
1404f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1405eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1406da3a660dSBarry Smith   }
140728988994SBarry Smith   if (rr) {
14087a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1409f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1410e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1411da3a660dSBarry Smith     for (i=0; i<n; i++) {
1412da3a660dSBarry Smith       x = r[i];
1413b43bac26SStefano Zampini       v = mat->v + i*mat->lda;
14142205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1415da3a660dSBarry Smith     }
1416f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1417eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1418da3a660dSBarry Smith   }
14193a40ed3dSBarry Smith   PetscFunctionReturn(0);
1420289bc588SBarry Smith }
1421289bc588SBarry Smith 
1422e0877f53SBarry Smith static PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1423289bc588SBarry Smith {
1424c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
142587828ca2SBarry Smith   PetscScalar    *v   = mat->v;
1426329f5518SBarry Smith   PetscReal      sum  = 0.0;
1427d0f46423SBarry Smith   PetscInt       lda  =mat->lda,m=A->rmap->n,i,j;
1428efee365bSSatish Balay   PetscErrorCode ierr;
142955659b69SBarry Smith 
14303a40ed3dSBarry Smith   PetscFunctionBegin;
1431289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1432a5ce6ee0Svictorle     if (lda>m) {
1433d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1434a5ce6ee0Svictorle         v = mat->v+j*lda;
1435a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1436a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1437a5ce6ee0Svictorle         }
1438a5ce6ee0Svictorle       }
1439a5ce6ee0Svictorle     } else {
1440570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1441570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1442570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1443570b7f6dSBarry Smith     }
1444570b7f6dSBarry Smith #else
1445d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1446329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1447289bc588SBarry Smith       }
1448a5ce6ee0Svictorle     }
14498f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1450570b7f6dSBarry Smith #endif
1451dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
14523a40ed3dSBarry Smith   } else if (type == NORM_1) {
1453064f8208SBarry Smith     *nrm = 0.0;
1454d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
14551b807ce4Svictorle       v   = mat->v + j*mat->lda;
1456289bc588SBarry Smith       sum = 0.0;
1457d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
145833a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1459289bc588SBarry Smith       }
1460064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1461289bc588SBarry Smith     }
1462eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
14633a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1464064f8208SBarry Smith     *nrm = 0.0;
1465d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1466289bc588SBarry Smith       v   = mat->v + j;
1467289bc588SBarry Smith       sum = 0.0;
1468d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
14691b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1470289bc588SBarry Smith       }
1471064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1472289bc588SBarry Smith     }
1473eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1474e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
14753a40ed3dSBarry Smith   PetscFunctionReturn(0);
1476289bc588SBarry Smith }
1477289bc588SBarry Smith 
1478e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1479289bc588SBarry Smith {
1480c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
148163ba0a88SBarry Smith   PetscErrorCode ierr;
148267e560aaSBarry Smith 
14833a40ed3dSBarry Smith   PetscFunctionBegin;
1484b5a2b587SKris Buschelman   switch (op) {
1485b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
14864e0d8c25SBarry Smith     aij->roworiented = flg;
1487b5a2b587SKris Buschelman     break;
1488512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1489b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
14903971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
14914e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
149213fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1493b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1494b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
14955021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
14965021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
14975021d80fSJed Brown     break;
14985021d80fSJed Brown   case MAT_SPD:
149977e54ba9SKris Buschelman   case MAT_SYMMETRIC:
150077e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
15019a4540c5SBarry Smith   case MAT_HERMITIAN:
15029a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
15035021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
150477e54ba9SKris Buschelman     break;
1505b5a2b587SKris Buschelman   default:
1506e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
15073a40ed3dSBarry Smith   }
15083a40ed3dSBarry Smith   PetscFunctionReturn(0);
1509289bc588SBarry Smith }
1510289bc588SBarry Smith 
1511e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
15126f0a148fSBarry Smith {
1513ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
15146849ba73SBarry Smith   PetscErrorCode ierr;
1515d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
15163a40ed3dSBarry Smith 
15173a40ed3dSBarry Smith   PetscFunctionBegin;
1518a5ce6ee0Svictorle   if (lda>m) {
1519d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1520a5ce6ee0Svictorle       ierr = PetscMemzero(l->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr);
1521a5ce6ee0Svictorle     }
1522a5ce6ee0Svictorle   } else {
1523d0f46423SBarry Smith     ierr = PetscMemzero(l->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
1524a5ce6ee0Svictorle   }
15253a40ed3dSBarry Smith   PetscFunctionReturn(0);
15266f0a148fSBarry Smith }
15276f0a148fSBarry Smith 
1528e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
15296f0a148fSBarry Smith {
153097b48c8fSBarry Smith   PetscErrorCode    ierr;
1531ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1532b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
153397b48c8fSBarry Smith   PetscScalar       *slot,*bb;
153497b48c8fSBarry Smith   const PetscScalar *xx;
153555659b69SBarry Smith 
15363a40ed3dSBarry Smith   PetscFunctionBegin;
1537b9679d65SBarry Smith #if defined(PETSC_USE_DEBUG)
1538b9679d65SBarry Smith   for (i=0; i<N; i++) {
1539b9679d65SBarry Smith     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1540b9679d65SBarry 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);
1541b9679d65SBarry Smith   }
1542b9679d65SBarry Smith #endif
1543b9679d65SBarry Smith 
154497b48c8fSBarry Smith   /* fix right hand side if needed */
154597b48c8fSBarry Smith   if (x && b) {
154697b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
154797b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
15482205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
154997b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
155097b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
155197b48c8fSBarry Smith   }
155297b48c8fSBarry Smith 
15536f0a148fSBarry Smith   for (i=0; i<N; i++) {
15546f0a148fSBarry Smith     slot = l->v + rows[i];
1555b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
15566f0a148fSBarry Smith   }
1557f4df32b1SMatthew Knepley   if (diag != 0.0) {
1558b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
15596f0a148fSBarry Smith     for (i=0; i<N; i++) {
1560b9679d65SBarry Smith       slot  = l->v + (m+1)*rows[i];
1561f4df32b1SMatthew Knepley       *slot = diag;
15626f0a148fSBarry Smith     }
15636f0a148fSBarry Smith   }
15643a40ed3dSBarry Smith   PetscFunctionReturn(0);
15656f0a148fSBarry Smith }
1566557bce09SLois Curfman McInnes 
1567e0877f53SBarry Smith static PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar *array[])
156864e87e97SBarry Smith {
1569c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
15703a40ed3dSBarry Smith 
15713a40ed3dSBarry Smith   PetscFunctionBegin;
1572e32f2f54SBarry 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");
157364e87e97SBarry Smith   *array = mat->v;
15743a40ed3dSBarry Smith   PetscFunctionReturn(0);
157564e87e97SBarry Smith }
15760754003eSLois Curfman McInnes 
1577e0877f53SBarry Smith static PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar *array[])
1578ff14e315SSatish Balay {
15793a40ed3dSBarry Smith   PetscFunctionBegin;
158009b544d4SBarry Smith   *array = 0; /* user cannot accidently use the array later */
15813a40ed3dSBarry Smith   PetscFunctionReturn(0);
1582ff14e315SSatish Balay }
15830754003eSLois Curfman McInnes 
1584dec5eb66SMatthew G Knepley /*@C
15858c778c55SBarry Smith    MatDenseGetArray - gives access to the array where the data for a SeqDense matrix is stored
158673a71a0fSBarry Smith 
158773a71a0fSBarry Smith    Not Collective
158873a71a0fSBarry Smith 
158973a71a0fSBarry Smith    Input Parameter:
1590579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
159173a71a0fSBarry Smith 
159273a71a0fSBarry Smith    Output Parameter:
159373a71a0fSBarry Smith .   array - pointer to the data
159473a71a0fSBarry Smith 
159573a71a0fSBarry Smith    Level: intermediate
159673a71a0fSBarry Smith 
15978c778c55SBarry Smith .seealso: MatDenseRestoreArray()
159873a71a0fSBarry Smith @*/
15998c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
160073a71a0fSBarry Smith {
160173a71a0fSBarry Smith   PetscErrorCode ierr;
160273a71a0fSBarry Smith 
160373a71a0fSBarry Smith   PetscFunctionBegin;
16048c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
160573a71a0fSBarry Smith   PetscFunctionReturn(0);
160673a71a0fSBarry Smith }
160773a71a0fSBarry Smith 
1608dec5eb66SMatthew G Knepley /*@C
1609579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
161073a71a0fSBarry Smith 
161173a71a0fSBarry Smith    Not Collective
161273a71a0fSBarry Smith 
161373a71a0fSBarry Smith    Input Parameters:
1614579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
161573a71a0fSBarry Smith .  array - pointer to the data
161673a71a0fSBarry Smith 
161773a71a0fSBarry Smith    Level: intermediate
161873a71a0fSBarry Smith 
16198c778c55SBarry Smith .seealso: MatDenseGetArray()
162073a71a0fSBarry Smith @*/
16218c778c55SBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
162273a71a0fSBarry Smith {
162373a71a0fSBarry Smith   PetscErrorCode ierr;
162473a71a0fSBarry Smith 
162573a71a0fSBarry Smith   PetscFunctionBegin;
16268c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
162773a71a0fSBarry Smith   PetscFunctionReturn(0);
162873a71a0fSBarry Smith }
162973a71a0fSBarry Smith 
16307dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
16310754003eSLois Curfman McInnes {
1632c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
16336849ba73SBarry Smith   PetscErrorCode ierr;
16345d0c19d7SBarry Smith   PetscInt       i,j,nrows,ncols;
16355d0c19d7SBarry Smith   const PetscInt *irow,*icol;
163687828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
16370754003eSLois Curfman McInnes   Mat            newmat;
16380754003eSLois Curfman McInnes 
16393a40ed3dSBarry Smith   PetscFunctionBegin;
164078b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
164178b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1642e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1643e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
16440754003eSLois Curfman McInnes 
1645182d2002SSatish Balay   /* Check submatrixcall */
1646182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
164713f74950SBarry Smith     PetscInt n_cols,n_rows;
1648182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
164921a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
1650f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
1651c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
165221a2c019SBarry Smith     }
1653182d2002SSatish Balay     newmat = *B;
1654182d2002SSatish Balay   } else {
16550754003eSLois Curfman McInnes     /* Create and fill new matrix */
1656ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
1657f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
16587adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
16590298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1660182d2002SSatish Balay   }
1661182d2002SSatish Balay 
1662182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1663182d2002SSatish Balay   bv = ((Mat_SeqDense*)newmat->data)->v;
1664182d2002SSatish Balay 
1665182d2002SSatish Balay   for (i=0; i<ncols; i++) {
16666de62eeeSBarry Smith     av = v + mat->lda*icol[i];
16672205254eSKarl Rupp     for (j=0; j<nrows; j++) *bv++ = av[irow[j]];
16680754003eSLois Curfman McInnes   }
1669182d2002SSatish Balay 
1670182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
16716d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16726d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16730754003eSLois Curfman McInnes 
16740754003eSLois Curfman McInnes   /* Free work space */
167578b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
167678b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1677182d2002SSatish Balay   *B   = newmat;
16783a40ed3dSBarry Smith   PetscFunctionReturn(0);
16790754003eSLois Curfman McInnes }
16800754003eSLois Curfman McInnes 
16817dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1682905e6a2fSBarry Smith {
16836849ba73SBarry Smith   PetscErrorCode ierr;
168413f74950SBarry Smith   PetscInt       i;
1685905e6a2fSBarry Smith 
16863a40ed3dSBarry Smith   PetscFunctionBegin;
1687905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1688df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
1689905e6a2fSBarry Smith   }
1690905e6a2fSBarry Smith 
1691905e6a2fSBarry Smith   for (i=0; i<n; i++) {
16927dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1693905e6a2fSBarry Smith   }
16943a40ed3dSBarry Smith   PetscFunctionReturn(0);
1695905e6a2fSBarry Smith }
1696905e6a2fSBarry Smith 
1697e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
1698c0aa2d19SHong Zhang {
1699c0aa2d19SHong Zhang   PetscFunctionBegin;
1700c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1701c0aa2d19SHong Zhang }
1702c0aa2d19SHong Zhang 
1703e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
1704c0aa2d19SHong Zhang {
1705c0aa2d19SHong Zhang   PetscFunctionBegin;
1706c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1707c0aa2d19SHong Zhang }
1708c0aa2d19SHong Zhang 
1709e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
17104b0e389bSBarry Smith {
17114b0e389bSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
17126849ba73SBarry Smith   PetscErrorCode ierr;
1713d0f46423SBarry Smith   PetscInt       lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
17143a40ed3dSBarry Smith 
17153a40ed3dSBarry Smith   PetscFunctionBegin;
171633f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
171733f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
1718cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
17193a40ed3dSBarry Smith     PetscFunctionReturn(0);
17203a40ed3dSBarry Smith   }
1721e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
1722a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
17230dbb7854Svictorle     for (j=0; j<n; j++) {
1724a5ce6ee0Svictorle       ierr = PetscMemcpy(b->v+j*lda2,a->v+j*lda1,m*sizeof(PetscScalar));CHKERRQ(ierr);
1725a5ce6ee0Svictorle     }
1726a5ce6ee0Svictorle   } else {
1727d0f46423SBarry Smith     ierr = PetscMemcpy(b->v,a->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
1728a5ce6ee0Svictorle   }
1729273d9f13SBarry Smith   PetscFunctionReturn(0);
1730273d9f13SBarry Smith }
1731273d9f13SBarry Smith 
1732e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
1733273d9f13SBarry Smith {
1734dfbe8321SBarry Smith   PetscErrorCode ierr;
1735273d9f13SBarry Smith 
1736273d9f13SBarry Smith   PetscFunctionBegin;
1737273d9f13SBarry Smith   ierr =  MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
17383a40ed3dSBarry Smith   PetscFunctionReturn(0);
17394b0e389bSBarry Smith }
17404b0e389bSBarry Smith 
1741ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
1742ba337c44SJed Brown {
1743ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1744ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1745ba337c44SJed Brown   PetscScalar  *aa = a->v;
1746ba337c44SJed Brown 
1747ba337c44SJed Brown   PetscFunctionBegin;
1748ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
1749ba337c44SJed Brown   PetscFunctionReturn(0);
1750ba337c44SJed Brown }
1751ba337c44SJed Brown 
1752ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
1753ba337c44SJed Brown {
1754ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1755ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1756ba337c44SJed Brown   PetscScalar  *aa = a->v;
1757ba337c44SJed Brown 
1758ba337c44SJed Brown   PetscFunctionBegin;
1759ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
1760ba337c44SJed Brown   PetscFunctionReturn(0);
1761ba337c44SJed Brown }
1762ba337c44SJed Brown 
1763ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
1764ba337c44SJed Brown {
1765ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1766ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1767ba337c44SJed Brown   PetscScalar  *aa = a->v;
1768ba337c44SJed Brown 
1769ba337c44SJed Brown   PetscFunctionBegin;
1770ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1771ba337c44SJed Brown   PetscFunctionReturn(0);
1772ba337c44SJed Brown }
1773284134d9SBarry Smith 
1774a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
1775150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
1776a9fe9ddaSSatish Balay {
1777a9fe9ddaSSatish Balay   PetscErrorCode ierr;
1778a9fe9ddaSSatish Balay 
1779a9fe9ddaSSatish Balay   PetscFunctionBegin;
1780a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
17813ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
1782a9fe9ddaSSatish Balay     ierr = MatMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
17833ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
1784a9fe9ddaSSatish Balay   }
17853ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
1786a9fe9ddaSSatish Balay   ierr = MatMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
17873ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
1788a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1789a9fe9ddaSSatish Balay }
1790a9fe9ddaSSatish Balay 
1791a9fe9ddaSSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
1792a9fe9ddaSSatish Balay {
1793ee16a9a1SHong Zhang   PetscErrorCode ierr;
1794d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
1795ee16a9a1SHong Zhang   Mat            Cmat;
1796a9fe9ddaSSatish Balay 
1797ee16a9a1SHong Zhang   PetscFunctionBegin;
1798e32f2f54SBarry 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);
1799ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
1800ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
1801ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
18020298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
1803d73949e8SHong Zhang 
1804ee16a9a1SHong Zhang   *C = Cmat;
1805ee16a9a1SHong Zhang   PetscFunctionReturn(0);
1806ee16a9a1SHong Zhang }
1807a9fe9ddaSSatish Balay 
1808a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
1809a9fe9ddaSSatish Balay {
1810a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1811a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
1812a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
18130805154bSBarry Smith   PetscBLASInt   m,n,k;
1814a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
1815c5df96a5SBarry Smith   PetscErrorCode ierr;
1816fd4e9aacSBarry Smith   PetscBool      flg;
1817a9fe9ddaSSatish Balay 
1818a9fe9ddaSSatish Balay   PetscFunctionBegin;
1819fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQDENSE,&flg);CHKERRQ(ierr);
1820fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Second matrix must be dense");
1821fd4e9aacSBarry Smith 
1822fd4e9aacSBarry Smith   /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/
1823fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
1824fd4e9aacSBarry Smith   if (flg) {
1825fd4e9aacSBarry Smith     C->ops->matmultnumeric = MatMatMultNumeric_SeqAIJ_SeqDense;
1826fd4e9aacSBarry Smith     ierr = (*C->ops->matmultnumeric)(A,B,C);CHKERRQ(ierr);
1827fd4e9aacSBarry Smith     PetscFunctionReturn(0);
1828fd4e9aacSBarry Smith   }
1829fd4e9aacSBarry Smith 
1830fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&flg);CHKERRQ(ierr);
1831fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"First matrix must be dense");
18328208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
18338208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
1834c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
18355ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
1836a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1837a9fe9ddaSSatish Balay }
1838a9fe9ddaSSatish Balay 
183975648e8dSHong Zhang PetscErrorCode MatTransposeMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
1840a9fe9ddaSSatish Balay {
1841a9fe9ddaSSatish Balay   PetscErrorCode ierr;
1842a9fe9ddaSSatish Balay 
1843a9fe9ddaSSatish Balay   PetscFunctionBegin;
1844a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
18453ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
184675648e8dSHong Zhang     ierr = MatTransposeMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
18473ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
1848a9fe9ddaSSatish Balay   }
18493ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
185075648e8dSHong Zhang   ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
18513ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
1852a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1853a9fe9ddaSSatish Balay }
1854a9fe9ddaSSatish Balay 
185575648e8dSHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
1856a9fe9ddaSSatish Balay {
1857ee16a9a1SHong Zhang   PetscErrorCode ierr;
1858d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
1859ee16a9a1SHong Zhang   Mat            Cmat;
1860a9fe9ddaSSatish Balay 
1861ee16a9a1SHong Zhang   PetscFunctionBegin;
1862e32f2f54SBarry 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);
1863ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
1864ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
1865ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
18660298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
18672205254eSKarl Rupp 
1868ee16a9a1SHong Zhang   Cmat->assembled = PETSC_TRUE;
18692205254eSKarl Rupp 
1870ee16a9a1SHong Zhang   *C = Cmat;
1871ee16a9a1SHong Zhang   PetscFunctionReturn(0);
1872ee16a9a1SHong Zhang }
1873a9fe9ddaSSatish Balay 
187475648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
1875a9fe9ddaSSatish Balay {
1876a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1877a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
1878a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
18790805154bSBarry Smith   PetscBLASInt   m,n,k;
1880a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
1881c5df96a5SBarry Smith   PetscErrorCode ierr;
1882a9fe9ddaSSatish Balay 
1883a9fe9ddaSSatish Balay   PetscFunctionBegin;
18848208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
18858208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
1886c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
18875ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
1888a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1889a9fe9ddaSSatish Balay }
1890985db425SBarry Smith 
1891e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
1892985db425SBarry Smith {
1893985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1894985db425SBarry Smith   PetscErrorCode ierr;
1895d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
1896985db425SBarry Smith   PetscScalar    *x;
1897985db425SBarry Smith   MatScalar      *aa = a->v;
1898985db425SBarry Smith 
1899985db425SBarry Smith   PetscFunctionBegin;
1900e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1901985db425SBarry Smith 
1902985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
1903985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1904985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
1905e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1906985db425SBarry Smith   for (i=0; i<m; i++) {
1907985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
1908985db425SBarry Smith     for (j=1; j<n; j++) {
1909985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
1910985db425SBarry Smith     }
1911985db425SBarry Smith   }
1912985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1913985db425SBarry Smith   PetscFunctionReturn(0);
1914985db425SBarry Smith }
1915985db425SBarry Smith 
1916e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
1917985db425SBarry Smith {
1918985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1919985db425SBarry Smith   PetscErrorCode ierr;
1920d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
1921985db425SBarry Smith   PetscScalar    *x;
1922985db425SBarry Smith   PetscReal      atmp;
1923985db425SBarry Smith   MatScalar      *aa = a->v;
1924985db425SBarry Smith 
1925985db425SBarry Smith   PetscFunctionBegin;
1926e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1927985db425SBarry Smith 
1928985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
1929985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1930985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
1931e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1932985db425SBarry Smith   for (i=0; i<m; i++) {
19339189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
1934985db425SBarry Smith     for (j=1; j<n; j++) {
1935985db425SBarry Smith       atmp = PetscAbsScalar(aa[i+m*j]);
1936985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
1937985db425SBarry Smith     }
1938985db425SBarry Smith   }
1939985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1940985db425SBarry Smith   PetscFunctionReturn(0);
1941985db425SBarry Smith }
1942985db425SBarry Smith 
1943e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
1944985db425SBarry Smith {
1945985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1946985db425SBarry Smith   PetscErrorCode ierr;
1947d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
1948985db425SBarry Smith   PetscScalar    *x;
1949985db425SBarry Smith   MatScalar      *aa = a->v;
1950985db425SBarry Smith 
1951985db425SBarry Smith   PetscFunctionBegin;
1952e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1953985db425SBarry Smith 
1954985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
1955985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1956985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
1957e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1958985db425SBarry Smith   for (i=0; i<m; i++) {
1959985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
1960985db425SBarry Smith     for (j=1; j<n; j++) {
1961985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
1962985db425SBarry Smith     }
1963985db425SBarry Smith   }
1964985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1965985db425SBarry Smith   PetscFunctionReturn(0);
1966985db425SBarry Smith }
1967985db425SBarry Smith 
1968e0877f53SBarry Smith static PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
19698d0534beSBarry Smith {
19708d0534beSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
19718d0534beSBarry Smith   PetscErrorCode ierr;
19728d0534beSBarry Smith   PetscScalar    *x;
19738d0534beSBarry Smith 
19748d0534beSBarry Smith   PetscFunctionBegin;
1975e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
19768d0534beSBarry Smith 
19778d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1978d0f46423SBarry Smith   ierr = PetscMemcpy(x,a->v+col*a->lda,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
19798d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
19808d0534beSBarry Smith   PetscFunctionReturn(0);
19818d0534beSBarry Smith }
19828d0534beSBarry Smith 
19830716a85fSBarry Smith 
19840716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
19850716a85fSBarry Smith {
19860716a85fSBarry Smith   PetscErrorCode ierr;
19870716a85fSBarry Smith   PetscInt       i,j,m,n;
19880716a85fSBarry Smith   PetscScalar    *a;
19890716a85fSBarry Smith 
19900716a85fSBarry Smith   PetscFunctionBegin;
19910716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
19920716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
19938c778c55SBarry Smith   ierr = MatDenseGetArray(A,&a);CHKERRQ(ierr);
19940716a85fSBarry Smith   if (type == NORM_2) {
19950716a85fSBarry Smith     for (i=0; i<n; i++) {
19960716a85fSBarry Smith       for (j=0; j<m; j++) {
19970716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
19980716a85fSBarry Smith       }
19990716a85fSBarry Smith       a += m;
20000716a85fSBarry Smith     }
20010716a85fSBarry Smith   } else if (type == NORM_1) {
20020716a85fSBarry Smith     for (i=0; i<n; i++) {
20030716a85fSBarry Smith       for (j=0; j<m; j++) {
20040716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
20050716a85fSBarry Smith       }
20060716a85fSBarry Smith       a += m;
20070716a85fSBarry Smith     }
20080716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
20090716a85fSBarry Smith     for (i=0; i<n; i++) {
20100716a85fSBarry Smith       for (j=0; j<m; j++) {
20110716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
20120716a85fSBarry Smith       }
20130716a85fSBarry Smith       a += m;
20140716a85fSBarry Smith     }
2015ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
20168c778c55SBarry Smith   ierr = MatDenseRestoreArray(A,&a);CHKERRQ(ierr);
20170716a85fSBarry Smith   if (type == NORM_2) {
20188f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
20190716a85fSBarry Smith   }
20200716a85fSBarry Smith   PetscFunctionReturn(0);
20210716a85fSBarry Smith }
20220716a85fSBarry Smith 
202373a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
202473a71a0fSBarry Smith {
202573a71a0fSBarry Smith   PetscErrorCode ierr;
202673a71a0fSBarry Smith   PetscScalar    *a;
202773a71a0fSBarry Smith   PetscInt       m,n,i;
202873a71a0fSBarry Smith 
202973a71a0fSBarry Smith   PetscFunctionBegin;
203073a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
20318c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
203273a71a0fSBarry Smith   for (i=0; i<m*n; i++) {
203373a71a0fSBarry Smith     ierr = PetscRandomGetValue(rctx,a+i);CHKERRQ(ierr);
203473a71a0fSBarry Smith   }
20358c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
203673a71a0fSBarry Smith   PetscFunctionReturn(0);
203773a71a0fSBarry Smith }
203873a71a0fSBarry Smith 
20393b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
20403b49f96aSBarry Smith {
20413b49f96aSBarry Smith   PetscFunctionBegin;
20423b49f96aSBarry Smith   *missing = PETSC_FALSE;
20433b49f96aSBarry Smith   PetscFunctionReturn(0);
20443b49f96aSBarry Smith }
204573a71a0fSBarry Smith 
2046abc3b08eSStefano Zampini 
2047289bc588SBarry Smith /* -------------------------------------------------------------------*/
2048a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2049905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2050905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2051905e6a2fSBarry Smith                                         MatMult_SeqDense,
205297304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
20537c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
20547c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2055db4efbfdSBarry Smith                                         0,
2056db4efbfdSBarry Smith                                         0,
2057db4efbfdSBarry Smith                                         0,
2058db4efbfdSBarry Smith                                 /* 10*/ 0,
2059905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2060905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
206141f059aeSBarry Smith                                         MatSOR_SeqDense,
2062ec8511deSBarry Smith                                         MatTranspose_SeqDense,
206397304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2064905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2065905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2066905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2067905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2068c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2069c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2070905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2071905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2072d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2073db4efbfdSBarry Smith                                         0,
2074db4efbfdSBarry Smith                                         0,
2075db4efbfdSBarry Smith                                         0,
2076db4efbfdSBarry Smith                                         0,
20774994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2078273d9f13SBarry Smith                                         0,
2079905e6a2fSBarry Smith                                         0,
208073a71a0fSBarry Smith                                         0,
208173a71a0fSBarry Smith                                         0,
2082d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2083a5ae1ecdSBarry Smith                                         0,
2084a5ae1ecdSBarry Smith                                         0,
2085a5ae1ecdSBarry Smith                                         0,
2086a5ae1ecdSBarry Smith                                         0,
2087d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
20887dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2089a5ae1ecdSBarry Smith                                         0,
20904b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2091a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2092d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2093a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
20947d68702bSBarry Smith                                         MatShift_Basic,
2095a5ae1ecdSBarry Smith                                         0,
20963f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
209773a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2098a5ae1ecdSBarry Smith                                         0,
2099a5ae1ecdSBarry Smith                                         0,
2100a5ae1ecdSBarry Smith                                         0,
2101a5ae1ecdSBarry Smith                                         0,
2102d519adbfSMatthew Knepley                                 /* 54*/ 0,
2103a5ae1ecdSBarry Smith                                         0,
2104a5ae1ecdSBarry Smith                                         0,
2105a5ae1ecdSBarry Smith                                         0,
2106a5ae1ecdSBarry Smith                                         0,
2107d519adbfSMatthew Knepley                                 /* 59*/ 0,
2108e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2109e03a110bSBarry Smith                                         MatView_SeqDense,
2110357abbc8SBarry Smith                                         0,
211197304618SKris Buschelman                                         0,
2112d519adbfSMatthew Knepley                                 /* 64*/ 0,
211397304618SKris Buschelman                                         0,
211497304618SKris Buschelman                                         0,
211597304618SKris Buschelman                                         0,
211697304618SKris Buschelman                                         0,
2117d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
211897304618SKris Buschelman                                         0,
211997304618SKris Buschelman                                         0,
212097304618SKris Buschelman                                         0,
212197304618SKris Buschelman                                         0,
2122d519adbfSMatthew Knepley                                 /* 74*/ 0,
212397304618SKris Buschelman                                         0,
212497304618SKris Buschelman                                         0,
212597304618SKris Buschelman                                         0,
212697304618SKris Buschelman                                         0,
2127d519adbfSMatthew Knepley                                 /* 79*/ 0,
212897304618SKris Buschelman                                         0,
212997304618SKris Buschelman                                         0,
213097304618SKris Buschelman                                         0,
21315bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2132865e5f61SKris Buschelman                                         0,
21331cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2134865e5f61SKris Buschelman                                         0,
2135865e5f61SKris Buschelman                                         0,
2136865e5f61SKris Buschelman                                         0,
2137d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqDense_SeqDense,
2138a9fe9ddaSSatish Balay                                         MatMatMultSymbolic_SeqDense_SeqDense,
2139a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2140abc3b08eSStefano Zampini                                         MatPtAP_SeqDense_SeqDense,
2141abc3b08eSStefano Zampini                                         MatPtAPSymbolic_SeqDense_SeqDense,
2142abc3b08eSStefano Zampini                                 /* 94*/ MatPtAPNumeric_SeqDense_SeqDense,
21435df89d91SHong Zhang                                         0,
21445df89d91SHong Zhang                                         0,
21455df89d91SHong Zhang                                         0,
2146284134d9SBarry Smith                                         0,
2147d519adbfSMatthew Knepley                                 /* 99*/ 0,
2148284134d9SBarry Smith                                         0,
2149284134d9SBarry Smith                                         0,
2150ba337c44SJed Brown                                         MatConjugate_SeqDense,
2151f73d5cc4SBarry Smith                                         0,
2152ba337c44SJed Brown                                 /*104*/ 0,
2153ba337c44SJed Brown                                         MatRealPart_SeqDense,
2154ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2155985db425SBarry Smith                                         0,
2156985db425SBarry Smith                                         0,
21578208b9aeSStefano Zampini                                 /*109*/ 0,
2158985db425SBarry Smith                                         0,
21598d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2160aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
21613b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2162aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2163aabbc4fbSShri Abhyankar                                         0,
2164aabbc4fbSShri Abhyankar                                         0,
2165aabbc4fbSShri Abhyankar                                         0,
2166aabbc4fbSShri Abhyankar                                         0,
2167aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2168aabbc4fbSShri Abhyankar                                         0,
2169aabbc4fbSShri Abhyankar                                         0,
21700716a85fSBarry Smith                                         0,
21710716a85fSBarry Smith                                         0,
21720716a85fSBarry Smith                                 /*124*/ 0,
21735df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
21745df89d91SHong Zhang                                         0,
21755df89d91SHong Zhang                                         0,
21765df89d91SHong Zhang                                         0,
21775df89d91SHong Zhang                                 /*129*/ 0,
217875648e8dSHong Zhang                                         MatTransposeMatMult_SeqDense_SeqDense,
217975648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqDense_SeqDense,
218075648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
21813964eb88SJed Brown                                         0,
21823964eb88SJed Brown                                 /*134*/ 0,
21833964eb88SJed Brown                                         0,
21843964eb88SJed Brown                                         0,
21853964eb88SJed Brown                                         0,
21863964eb88SJed Brown                                         0,
21873964eb88SJed Brown                                 /*139*/ 0,
2188f9426fe0SMark Adams                                         0,
21893964eb88SJed Brown                                         0
2190985db425SBarry Smith };
219190ace30eSBarry Smith 
21924b828684SBarry Smith /*@C
2193fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2194d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2195d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2196289bc588SBarry Smith 
2197db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2198db81eaa0SLois Curfman McInnes 
219920563c6bSBarry Smith    Input Parameters:
2200db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
22010c775827SLois Curfman McInnes .  m - number of rows
220218f449edSLois Curfman McInnes .  n - number of columns
22030298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2204dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
220520563c6bSBarry Smith 
220620563c6bSBarry Smith    Output Parameter:
220744cd7ae7SLois Curfman McInnes .  A - the matrix
220820563c6bSBarry Smith 
2209b259b22eSLois Curfman McInnes    Notes:
221018f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
221118f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
22120298fd71SBarry Smith    set data=NULL.
221318f449edSLois Curfman McInnes 
2214027ccd11SLois Curfman McInnes    Level: intermediate
2215027ccd11SLois Curfman McInnes 
2216dbd7a890SLois Curfman McInnes .keywords: dense, matrix, LAPACK, BLAS
2217d65003e9SLois Curfman McInnes 
221869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
221920563c6bSBarry Smith @*/
22207087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2221289bc588SBarry Smith {
2222dfbe8321SBarry Smith   PetscErrorCode ierr;
22233b2fbd54SBarry Smith 
22243a40ed3dSBarry Smith   PetscFunctionBegin;
2225f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2226f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2227273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2228273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2229273d9f13SBarry Smith   PetscFunctionReturn(0);
2230273d9f13SBarry Smith }
2231273d9f13SBarry Smith 
2232273d9f13SBarry Smith /*@C
2233273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2234273d9f13SBarry Smith 
2235273d9f13SBarry Smith    Collective on MPI_Comm
2236273d9f13SBarry Smith 
2237273d9f13SBarry Smith    Input Parameters:
22381c4f3114SJed Brown +  B - the matrix
22390298fd71SBarry Smith -  data - the array (or NULL)
2240273d9f13SBarry Smith 
2241273d9f13SBarry Smith    Notes:
2242273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2243273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2244284134d9SBarry Smith    need not call this routine.
2245273d9f13SBarry Smith 
2246273d9f13SBarry Smith    Level: intermediate
2247273d9f13SBarry Smith 
2248273d9f13SBarry Smith .keywords: dense, matrix, LAPACK, BLAS
2249273d9f13SBarry Smith 
225069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA()
2251867c911aSBarry Smith 
2252273d9f13SBarry Smith @*/
22537087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2254273d9f13SBarry Smith {
22554ac538c5SBarry Smith   PetscErrorCode ierr;
2256a23d5eceSKris Buschelman 
2257a23d5eceSKris Buschelman   PetscFunctionBegin;
22584ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2259a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2260a23d5eceSKris Buschelman }
2261a23d5eceSKris Buschelman 
22627087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2263a23d5eceSKris Buschelman {
2264273d9f13SBarry Smith   Mat_SeqDense   *b;
2265dfbe8321SBarry Smith   PetscErrorCode ierr;
2266273d9f13SBarry Smith 
2267273d9f13SBarry Smith   PetscFunctionBegin;
2268273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2269a868139aSShri Abhyankar 
227034ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
227134ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
227234ef9618SShri Abhyankar 
2273273d9f13SBarry Smith   b       = (Mat_SeqDense*)B->data;
227486d161a7SShri Abhyankar   b->Mmax = B->rmap->n;
227586d161a7SShri Abhyankar   b->Nmax = B->cmap->n;
227686d161a7SShri Abhyankar   if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n;
227786d161a7SShri Abhyankar 
2278220afb94SBarry Smith   ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr);
22799e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
22809e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2281e92229d0SSatish Balay     ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr);
22823bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
22832205254eSKarl Rupp 
22849e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2285273d9f13SBarry Smith   } else { /* user-allocated storage */
22869e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2287273d9f13SBarry Smith     b->v          = data;
2288273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2289273d9f13SBarry Smith   }
22900450473dSBarry Smith   B->assembled = PETSC_TRUE;
2291273d9f13SBarry Smith   PetscFunctionReturn(0);
2292273d9f13SBarry Smith }
2293273d9f13SBarry Smith 
229465b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2295cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
22968baccfbdSHong Zhang {
2297d77f618aSHong Zhang   Mat            mat_elemental;
2298d77f618aSHong Zhang   PetscErrorCode ierr;
2299d77f618aSHong Zhang   PetscScalar    *array,*v_colwise;
2300d77f618aSHong Zhang   PetscInt       M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2301d77f618aSHong Zhang 
23028baccfbdSHong Zhang   PetscFunctionBegin;
2303d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
2304d77f618aSHong Zhang   ierr = MatDenseGetArray(A,&array);CHKERRQ(ierr);
2305d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2306d77f618aSHong Zhang   k = 0;
2307d77f618aSHong Zhang   for (j=0; j<N; j++) {
2308d77f618aSHong Zhang     cols[j] = j;
2309d77f618aSHong Zhang     for (i=0; i<M; i++) {
2310d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2311d77f618aSHong Zhang     }
2312d77f618aSHong Zhang   }
2313d77f618aSHong Zhang   for (i=0; i<M; i++) {
2314d77f618aSHong Zhang     rows[i] = i;
2315d77f618aSHong Zhang   }
2316d77f618aSHong Zhang   ierr = MatDenseRestoreArray(A,&array);CHKERRQ(ierr);
2317d77f618aSHong Zhang 
2318d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2319d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2320d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2321d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2322d77f618aSHong Zhang 
2323d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2324d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2325d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2326d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2327d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2328d77f618aSHong Zhang 
2329511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
233028be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2331d77f618aSHong Zhang   } else {
2332d77f618aSHong Zhang     *newmat = mat_elemental;
2333d77f618aSHong Zhang   }
23348baccfbdSHong Zhang   PetscFunctionReturn(0);
23358baccfbdSHong Zhang }
233665b80a83SHong Zhang #endif
23378baccfbdSHong Zhang 
23381b807ce4Svictorle /*@C
23391b807ce4Svictorle   MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array
23401b807ce4Svictorle 
23411b807ce4Svictorle   Input parameter:
23421b807ce4Svictorle + A - the matrix
23431b807ce4Svictorle - lda - the leading dimension
23441b807ce4Svictorle 
23451b807ce4Svictorle   Notes:
2346867c911aSBarry Smith   This routine is to be used in conjunction with MatSeqDenseSetPreallocation();
23471b807ce4Svictorle   it asserts that the preallocation has a leading dimension (the LDA parameter
23481b807ce4Svictorle   of Blas and Lapack fame) larger than M, the first dimension of the matrix.
23491b807ce4Svictorle 
23501b807ce4Svictorle   Level: intermediate
23511b807ce4Svictorle 
23521b807ce4Svictorle .keywords: dense, matrix, LAPACK, BLAS
23531b807ce4Svictorle 
2354284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize()
2355867c911aSBarry Smith 
23561b807ce4Svictorle @*/
23577087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetLDA(Mat B,PetscInt lda)
23581b807ce4Svictorle {
23591b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
236021a2c019SBarry Smith 
23611b807ce4Svictorle   PetscFunctionBegin;
2362e32f2f54SBarry 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);
23631b807ce4Svictorle   b->lda       = lda;
236421a2c019SBarry Smith   b->changelda = PETSC_FALSE;
236521a2c019SBarry Smith   b->Mmax      = PetscMax(b->Mmax,lda);
23661b807ce4Svictorle   PetscFunctionReturn(0);
23671b807ce4Svictorle }
23681b807ce4Svictorle 
23690bad9183SKris Buschelman /*MC
2370fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
23710bad9183SKris Buschelman 
23720bad9183SKris Buschelman    Options Database Keys:
23730bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
23740bad9183SKris Buschelman 
23750bad9183SKris Buschelman   Level: beginner
23760bad9183SKris Buschelman 
237789665df3SBarry Smith .seealso: MatCreateSeqDense()
237889665df3SBarry Smith 
23790bad9183SKris Buschelman M*/
23800bad9183SKris Buschelman 
23818cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqDense(Mat B)
2382273d9f13SBarry Smith {
2383273d9f13SBarry Smith   Mat_SeqDense   *b;
2384dfbe8321SBarry Smith   PetscErrorCode ierr;
23857c334f02SBarry Smith   PetscMPIInt    size;
2386273d9f13SBarry Smith 
2387273d9f13SBarry Smith   PetscFunctionBegin;
2388ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
2389e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
239055659b69SBarry Smith 
2391b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
2392549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
239344cd7ae7SLois Curfman McInnes   B->data = (void*)b;
239418f449edSLois Curfman McInnes 
2395273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
23964e220ebcSLois Curfman McInnes 
2397bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2398bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2399bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
24008baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
24018baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
24028baccfbdSHong Zhang #endif
2403bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
2404bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaij_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2405bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2406bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2407abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaij_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
24083bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaij_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
24093bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
24103bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
241117667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
24123a40ed3dSBarry Smith   PetscFunctionReturn(0);
2413289bc588SBarry Smith }
2414