xref: /petsc/src/mat/impls/dense/seq/dense.c (revision d3042a70f471d64055a67fbedc03cbed6f0fa57d)
1be1d678aSKris Buschelman 
267e560aaSBarry Smith /*
367e560aaSBarry Smith      Defines the basic matrix operations for sequential dense.
467e560aaSBarry Smith */
5289bc588SBarry Smith 
6dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/
7c6db04a5SJed Brown #include <petscblaslapack.h>
8289bc588SBarry Smith 
96a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h>
10b2573a8aSBarry Smith 
113f49a652SStefano Zampini PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
123f49a652SStefano Zampini {
133f49a652SStefano Zampini   PetscErrorCode    ierr;
143f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
153f49a652SStefano Zampini   PetscInt          m  = l->lda, n = A->cmap->n,r = A->rmap->n, i,j;
163f49a652SStefano Zampini   PetscScalar       *slot,*bb;
173f49a652SStefano Zampini   const PetscScalar *xx;
183f49a652SStefano Zampini 
193f49a652SStefano Zampini   PetscFunctionBegin;
203f49a652SStefano Zampini #if defined(PETSC_USE_DEBUG)
213f49a652SStefano Zampini   for (i=0; i<N; i++) {
223f49a652SStefano Zampini     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
233f49a652SStefano Zampini     if (rows[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D requested to be zeroed greater than or equal number of rows %D",rows[i],A->rmap->n);
243f49a652SStefano Zampini     if (rows[i] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Col %D requested to be zeroed greater than or equal number of cols %D",rows[i],A->cmap->n);
253f49a652SStefano Zampini   }
263f49a652SStefano Zampini #endif
273f49a652SStefano Zampini 
283f49a652SStefano Zampini   /* fix right hand side if needed */
293f49a652SStefano Zampini   if (x && b) {
303f49a652SStefano Zampini     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
313f49a652SStefano Zampini     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
323f49a652SStefano Zampini     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
333f49a652SStefano Zampini     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
343f49a652SStefano Zampini     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
353f49a652SStefano Zampini   }
363f49a652SStefano Zampini 
373f49a652SStefano Zampini   for (i=0; i<N; i++) {
383f49a652SStefano Zampini     slot = l->v + rows[i]*m;
393f49a652SStefano Zampini     ierr = PetscMemzero(slot,r*sizeof(PetscScalar));CHKERRQ(ierr);
403f49a652SStefano Zampini   }
413f49a652SStefano Zampini   for (i=0; i<N; i++) {
423f49a652SStefano Zampini     slot = l->v + rows[i];
433f49a652SStefano Zampini     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
443f49a652SStefano Zampini   }
453f49a652SStefano Zampini   if (diag != 0.0) {
463f49a652SStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
473f49a652SStefano Zampini     for (i=0; i<N; i++) {
483f49a652SStefano Zampini       slot  = l->v + (m+1)*rows[i];
493f49a652SStefano Zampini       *slot = diag;
503f49a652SStefano Zampini     }
513f49a652SStefano Zampini   }
523f49a652SStefano Zampini   PetscFunctionReturn(0);
533f49a652SStefano Zampini }
543f49a652SStefano Zampini 
55abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C)
56abc3b08eSStefano Zampini {
57abc3b08eSStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)(C->data);
58abc3b08eSStefano Zampini   PetscErrorCode ierr;
59abc3b08eSStefano Zampini 
60abc3b08eSStefano Zampini   PetscFunctionBegin;
61abc3b08eSStefano Zampini   ierr = MatMatMultNumeric_SeqDense_SeqDense(A,P,c->ptapwork);CHKERRQ(ierr);
62abc3b08eSStefano Zampini   ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(P,c->ptapwork,C);CHKERRQ(ierr);
63abc3b08eSStefano Zampini   PetscFunctionReturn(0);
64abc3b08eSStefano Zampini }
65abc3b08eSStefano Zampini 
66abc3b08eSStefano Zampini PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat *C)
67abc3b08eSStefano Zampini {
68abc3b08eSStefano Zampini   Mat_SeqDense   *c;
69abc3b08eSStefano Zampini   PetscErrorCode ierr;
70abc3b08eSStefano Zampini 
71abc3b08eSStefano Zampini   PetscFunctionBegin;
72abc3b08eSStefano Zampini   ierr = MatCreateSeqDense(PetscObjectComm((PetscObject)A),P->cmap->N,P->cmap->N,NULL,C);CHKERRQ(ierr);
73abc3b08eSStefano Zampini   c = (Mat_SeqDense*)((*C)->data);
74abc3b08eSStefano Zampini   ierr = MatCreateSeqDense(PetscObjectComm((PetscObject)A),A->rmap->N,P->cmap->N,NULL,&c->ptapwork);CHKERRQ(ierr);
75abc3b08eSStefano Zampini   PetscFunctionReturn(0);
76abc3b08eSStefano Zampini }
77abc3b08eSStefano Zampini 
78150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatPtAP_SeqDense_SeqDense(Mat A,Mat P,MatReuse reuse,PetscReal fill,Mat *C)
79abc3b08eSStefano Zampini {
80abc3b08eSStefano Zampini   PetscErrorCode ierr;
81abc3b08eSStefano Zampini 
82abc3b08eSStefano Zampini   PetscFunctionBegin;
83abc3b08eSStefano Zampini   if (reuse == MAT_INITIAL_MATRIX) {
84abc3b08eSStefano Zampini     ierr = MatPtAPSymbolic_SeqDense_SeqDense(A,P,fill,C);CHKERRQ(ierr);
85abc3b08eSStefano Zampini   }
86abc3b08eSStefano Zampini   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
87abc3b08eSStefano Zampini   ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
88abc3b08eSStefano Zampini   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
89abc3b08eSStefano Zampini   PetscFunctionReturn(0);
90abc3b08eSStefano Zampini }
91abc3b08eSStefano Zampini 
92cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
93b49cda9fSStefano Zampini {
94a13144ffSStefano Zampini   Mat            B = NULL;
95b49cda9fSStefano Zampini   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
96b49cda9fSStefano Zampini   Mat_SeqDense   *b;
97b49cda9fSStefano Zampini   PetscErrorCode ierr;
98b49cda9fSStefano Zampini   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i;
99b49cda9fSStefano Zampini   MatScalar      *av=a->a;
100a13144ffSStefano Zampini   PetscBool      isseqdense;
101b49cda9fSStefano Zampini 
102b49cda9fSStefano Zampini   PetscFunctionBegin;
103a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
104a13144ffSStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense);CHKERRQ(ierr);
105a13144ffSStefano Zampini     if (!isseqdense) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type);
106a13144ffSStefano Zampini   }
107a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
108b49cda9fSStefano Zampini     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
109b49cda9fSStefano Zampini     ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
110b49cda9fSStefano Zampini     ierr = MatSetType(B,MATSEQDENSE);CHKERRQ(ierr);
111b49cda9fSStefano Zampini     ierr = MatSeqDenseSetPreallocation(B,NULL);CHKERRQ(ierr);
112b49cda9fSStefano Zampini     b    = (Mat_SeqDense*)(B->data);
113a13144ffSStefano Zampini   } else {
114a13144ffSStefano Zampini     b    = (Mat_SeqDense*)((*newmat)->data);
115a13144ffSStefano Zampini     ierr = PetscMemzero(b->v,m*n*sizeof(PetscScalar));CHKERRQ(ierr);
116a13144ffSStefano Zampini   }
117b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
118b49cda9fSStefano Zampini     PetscInt j;
119b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
120b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
121b49cda9fSStefano Zampini       aj++;
122b49cda9fSStefano Zampini       av++;
123b49cda9fSStefano Zampini     }
124b49cda9fSStefano Zampini     ai++;
125b49cda9fSStefano Zampini   }
126b49cda9fSStefano Zampini 
127511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
128a13144ffSStefano Zampini     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
129a13144ffSStefano Zampini     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
13028be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
131b49cda9fSStefano Zampini   } else {
132a13144ffSStefano Zampini     if (B) *newmat = B;
133a13144ffSStefano Zampini     ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
134a13144ffSStefano Zampini     ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
135b49cda9fSStefano Zampini   }
136b49cda9fSStefano Zampini   PetscFunctionReturn(0);
137b49cda9fSStefano Zampini }
138b49cda9fSStefano Zampini 
139cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
1406a63e612SBarry Smith {
1416a63e612SBarry Smith   Mat            B;
1426a63e612SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1436a63e612SBarry Smith   PetscErrorCode ierr;
1449399e1b8SMatthew G. Knepley   PetscInt       i, j;
1459399e1b8SMatthew G. Knepley   PetscInt       *rows, *nnz;
1469399e1b8SMatthew G. Knepley   MatScalar      *aa = a->v, *vals;
1476a63e612SBarry Smith 
1486a63e612SBarry Smith   PetscFunctionBegin;
149ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
1506a63e612SBarry Smith   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
1516a63e612SBarry Smith   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
1529399e1b8SMatthew G. Knepley   ierr = PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals);CHKERRQ(ierr);
1539399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
1549399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) ++nnz[i];
1556a63e612SBarry Smith     aa += a->lda;
1566a63e612SBarry Smith   }
1579399e1b8SMatthew G. Knepley   ierr = MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz);CHKERRQ(ierr);
1589399e1b8SMatthew G. Knepley   aa = a->v;
1599399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
1609399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
1619399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) {rows[numRows] = i; vals[numRows++] = aa[i];}
1629399e1b8SMatthew G. Knepley     ierr = MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr);
1639399e1b8SMatthew G. Knepley     aa  += a->lda;
1649399e1b8SMatthew G. Knepley   }
1659399e1b8SMatthew G. Knepley   ierr = PetscFree3(rows,nnz,vals);CHKERRQ(ierr);
1666a63e612SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1676a63e612SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1686a63e612SBarry Smith 
169511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
17028be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
1716a63e612SBarry Smith   } else {
1726a63e612SBarry Smith     *newmat = B;
1736a63e612SBarry Smith   }
1746a63e612SBarry Smith   PetscFunctionReturn(0);
1756a63e612SBarry Smith }
1766a63e612SBarry Smith 
177e0877f53SBarry Smith static PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
1781987afe7SBarry Smith {
1791987afe7SBarry Smith   Mat_SeqDense   *x     = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
180f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
18113f74950SBarry Smith   PetscInt       j;
1820805154bSBarry Smith   PetscBLASInt   N,m,ldax,lday,one = 1;
183efee365bSSatish Balay   PetscErrorCode ierr;
1843a40ed3dSBarry Smith 
1853a40ed3dSBarry Smith   PetscFunctionBegin;
186c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n*X->cmap->n,&N);CHKERRQ(ierr);
187c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n,&m);CHKERRQ(ierr);
188c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->lda,&ldax);CHKERRQ(ierr);
189c5df96a5SBarry Smith   ierr = PetscBLASIntCast(y->lda,&lday);CHKERRQ(ierr);
190a5ce6ee0Svictorle   if (ldax>m || lday>m) {
191d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
1928b83055fSJed Brown       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&oalpha,x->v+j*ldax,&one,y->v+j*lday,&one));
193a5ce6ee0Svictorle     }
194a5ce6ee0Svictorle   } else {
1958b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&oalpha,x->v,&one,y->v,&one));
196a5ce6ee0Svictorle   }
197a3fa217bSJose E. Roman   ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr);
1980450473dSBarry Smith   ierr = PetscLogFlops(PetscMax(2*N-1,0));CHKERRQ(ierr);
1993a40ed3dSBarry Smith   PetscFunctionReturn(0);
2001987afe7SBarry Smith }
2011987afe7SBarry Smith 
202e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
203289bc588SBarry Smith {
204d0f46423SBarry Smith   PetscInt N = A->rmap->n*A->cmap->n;
2053a40ed3dSBarry Smith 
2063a40ed3dSBarry Smith   PetscFunctionBegin;
2074e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
2084e220ebcSLois Curfman McInnes   info->nz_allocated      = (double)N;
2096de62eeeSBarry Smith   info->nz_used           = (double)N;
2106de62eeeSBarry Smith   info->nz_unneeded       = (double)0;
2114e220ebcSLois Curfman McInnes   info->assemblies        = (double)A->num_ass;
2124e220ebcSLois Curfman McInnes   info->mallocs           = 0;
2137adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
2144e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
2154e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
2164e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
2173a40ed3dSBarry Smith   PetscFunctionReturn(0);
218289bc588SBarry Smith }
219289bc588SBarry Smith 
220e0877f53SBarry Smith static PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
22180cd9d93SLois Curfman McInnes {
222273d9f13SBarry Smith   Mat_SeqDense   *a     = (Mat_SeqDense*)A->data;
223f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
224efee365bSSatish Balay   PetscErrorCode ierr;
225c5df96a5SBarry Smith   PetscBLASInt   one = 1,j,nz,lda;
22680cd9d93SLois Curfman McInnes 
2273a40ed3dSBarry Smith   PetscFunctionBegin;
228c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->lda,&lda);CHKERRQ(ierr);
229d0f46423SBarry Smith   if (lda>A->rmap->n) {
230c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n,&nz);CHKERRQ(ierr);
231d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2328b83055fSJed Brown       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&oalpha,a->v+j*lda,&one));
233a5ce6ee0Svictorle     }
234a5ce6ee0Svictorle   } else {
235c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz);CHKERRQ(ierr);
2368b83055fSJed Brown     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&oalpha,a->v,&one));
237a5ce6ee0Svictorle   }
238efee365bSSatish Balay   ierr = PetscLogFlops(nz);CHKERRQ(ierr);
2393a40ed3dSBarry Smith   PetscFunctionReturn(0);
24080cd9d93SLois Curfman McInnes }
24180cd9d93SLois Curfman McInnes 
242e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
2431cbb95d3SBarry Smith {
2441cbb95d3SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
245d0f46423SBarry Smith   PetscInt     i,j,m = A->rmap->n,N;
2461cbb95d3SBarry Smith   PetscScalar  *v = a->v;
2471cbb95d3SBarry Smith 
2481cbb95d3SBarry Smith   PetscFunctionBegin;
2491cbb95d3SBarry Smith   *fl = PETSC_FALSE;
250d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
2511cbb95d3SBarry Smith   N = a->lda;
2521cbb95d3SBarry Smith 
2531cbb95d3SBarry Smith   for (i=0; i<m; i++) {
2541cbb95d3SBarry Smith     for (j=i+1; j<m; j++) {
2551cbb95d3SBarry Smith       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) PetscFunctionReturn(0);
2561cbb95d3SBarry Smith     }
2571cbb95d3SBarry Smith   }
2581cbb95d3SBarry Smith   *fl = PETSC_TRUE;
2591cbb95d3SBarry Smith   PetscFunctionReturn(0);
2601cbb95d3SBarry Smith }
2611cbb95d3SBarry Smith 
262e0877f53SBarry Smith static PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
263b24902e0SBarry Smith {
264b24902e0SBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data,*l;
265b24902e0SBarry Smith   PetscErrorCode ierr;
266b24902e0SBarry Smith   PetscInt       lda = (PetscInt)mat->lda,j,m;
267b24902e0SBarry Smith 
268b24902e0SBarry Smith   PetscFunctionBegin;
269aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr);
270aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr);
2710298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr);
272b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
273b24902e0SBarry Smith     l = (Mat_SeqDense*)newi->data;
274d0f46423SBarry Smith     if (lda>A->rmap->n) {
275d0f46423SBarry Smith       m = A->rmap->n;
276d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
277b24902e0SBarry Smith         ierr = PetscMemcpy(l->v+j*m,mat->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr);
278b24902e0SBarry Smith       }
279b24902e0SBarry Smith     } else {
280d0f46423SBarry Smith       ierr = PetscMemcpy(l->v,mat->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
281b24902e0SBarry Smith     }
282b24902e0SBarry Smith   }
283b24902e0SBarry Smith   newi->assembled = PETSC_TRUE;
284b24902e0SBarry Smith   PetscFunctionReturn(0);
285b24902e0SBarry Smith }
286b24902e0SBarry Smith 
287e0877f53SBarry Smith static PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
28802cad45dSBarry Smith {
2896849ba73SBarry Smith   PetscErrorCode ierr;
29002cad45dSBarry Smith 
2913a40ed3dSBarry Smith   PetscFunctionBegin;
292ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr);
293d0f46423SBarry Smith   ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
2945c9eb25fSBarry Smith   ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
295719d5645SBarry Smith   ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr);
296b24902e0SBarry Smith   PetscFunctionReturn(0);
297b24902e0SBarry Smith }
298b24902e0SBarry Smith 
2996ee01492SSatish Balay 
300e0877f53SBarry Smith static PetscErrorCode MatLUFactor_SeqDense(Mat,IS,IS,const MatFactorInfo*);
301719d5645SBarry Smith 
302e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
303289bc588SBarry Smith {
3044482741eSBarry Smith   MatFactorInfo  info;
305a093e273SMatthew Knepley   PetscErrorCode ierr;
3063a40ed3dSBarry Smith 
3073a40ed3dSBarry Smith   PetscFunctionBegin;
308c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
309719d5645SBarry Smith   ierr = MatLUFactor_SeqDense(fact,0,0,&info);CHKERRQ(ierr);
3103a40ed3dSBarry Smith   PetscFunctionReturn(0);
311289bc588SBarry Smith }
3126ee01492SSatish Balay 
313e0877f53SBarry Smith static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy)
314289bc588SBarry Smith {
315c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
3166849ba73SBarry Smith   PetscErrorCode    ierr;
317f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
318f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
319c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
32067e560aaSBarry Smith 
3213a40ed3dSBarry Smith   PetscFunctionBegin;
322c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
323f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
3241ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
325d0f46423SBarry Smith   ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
326d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_LU) {
327ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
328e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
329ae7cfcebSSatish Balay #else
3308b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
331e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
332ae7cfcebSSatish Balay #endif
333d5f3da31SBarry Smith   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
334ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
335e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
336ae7cfcebSSatish Balay #else
3378b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
338e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
339ae7cfcebSSatish Balay #endif
3402205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
341f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
3421ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
343dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
3443a40ed3dSBarry Smith   PetscFunctionReturn(0);
345289bc588SBarry Smith }
3466ee01492SSatish Balay 
347e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X)
34885e2c93fSHong Zhang {
34985e2c93fSHong Zhang   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
35085e2c93fSHong Zhang   PetscErrorCode ierr;
35185e2c93fSHong Zhang   PetscScalar    *b,*x;
352efb80c78SLisandro Dalcin   PetscInt       n;
353783b601eSJed Brown   PetscBLASInt   nrhs,info,m;
354bda8bf91SBarry Smith   PetscBool      flg;
35585e2c93fSHong Zhang 
35685e2c93fSHong Zhang   PetscFunctionBegin;
357c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
3580298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
359ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3600298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
361ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
362bda8bf91SBarry Smith 
3630298fd71SBarry Smith   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
364c5df96a5SBarry Smith   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
3658c778c55SBarry Smith   ierr = MatDenseGetArray(B,&b);CHKERRQ(ierr);
3668c778c55SBarry Smith   ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr);
36785e2c93fSHong Zhang 
368f272c775SHong Zhang   ierr = PetscMemcpy(x,b,m*nrhs*sizeof(PetscScalar));CHKERRQ(ierr);
36985e2c93fSHong Zhang 
37085e2c93fSHong Zhang   if (A->factortype == MAT_FACTOR_LU) {
37185e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_GETRS)
37285e2c93fSHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
37385e2c93fSHong Zhang #else
3748b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
37585e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
37685e2c93fSHong Zhang #endif
37785e2c93fSHong Zhang   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
37885e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_POTRS)
37985e2c93fSHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
38085e2c93fSHong Zhang #else
3818b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
38285e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
38385e2c93fSHong Zhang #endif
3842205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
38585e2c93fSHong Zhang 
3868c778c55SBarry Smith   ierr = MatDenseRestoreArray(B,&b);CHKERRQ(ierr);
3878c778c55SBarry Smith   ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr);
38885e2c93fSHong Zhang   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
38985e2c93fSHong Zhang   PetscFunctionReturn(0);
39085e2c93fSHong Zhang }
39185e2c93fSHong Zhang 
392e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
393da3a660dSBarry Smith {
394c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
395dfbe8321SBarry Smith   PetscErrorCode    ierr;
396f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
397f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
398c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
39967e560aaSBarry Smith 
4003a40ed3dSBarry Smith   PetscFunctionBegin;
401c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
402f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4031ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
404d0f46423SBarry Smith   ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
405752f5567SLois Curfman McInnes   /* assume if pivots exist then use LU; else Cholesky */
406da3a660dSBarry Smith   if (mat->pivots) {
407ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
408e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
409ae7cfcebSSatish Balay #else
4108b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
411e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve");
412ae7cfcebSSatish Balay #endif
4137a97a34bSBarry Smith   } else {
414ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
415e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
416ae7cfcebSSatish Balay #else
4178b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
418e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve");
419ae7cfcebSSatish Balay #endif
420da3a660dSBarry Smith   }
421f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4221ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
423dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
4243a40ed3dSBarry Smith   PetscFunctionReturn(0);
425da3a660dSBarry Smith }
4266ee01492SSatish Balay 
427e0877f53SBarry Smith static PetscErrorCode MatSolveAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
428da3a660dSBarry Smith {
429c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
430dfbe8321SBarry Smith   PetscErrorCode    ierr;
431f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
432f1ceaac6SMatthew G. Knepley   PetscScalar       *y,sone = 1.0;
433da3a660dSBarry Smith   Vec               tmp = 0;
434c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
43567e560aaSBarry Smith 
4363a40ed3dSBarry Smith   PetscFunctionBegin;
437c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
438f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4391ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
440d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
441da3a660dSBarry Smith   if (yy == zz) {
44278b31e54SBarry Smith     ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr);
4433bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)tmp);CHKERRQ(ierr);
44478b31e54SBarry Smith     ierr = VecCopy(yy,tmp);CHKERRQ(ierr);
445da3a660dSBarry Smith   }
446d0f46423SBarry Smith   ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
447752f5567SLois Curfman McInnes   /* assume if pivots exist then use LU; else Cholesky */
448da3a660dSBarry Smith   if (mat->pivots) {
449ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
450e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
451ae7cfcebSSatish Balay #else
4528b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
453e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad solve");
454ae7cfcebSSatish Balay #endif
455a8c6a408SBarry Smith   } else {
456ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
457e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
458ae7cfcebSSatish Balay #else
4598b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
460e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad solve");
461ae7cfcebSSatish Balay #endif
462da3a660dSBarry Smith   }
4636bf464f9SBarry Smith   if (tmp) {
4646bf464f9SBarry Smith     ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr);
4656bf464f9SBarry Smith     ierr = VecDestroy(&tmp);CHKERRQ(ierr);
4666bf464f9SBarry Smith   } else {
4676bf464f9SBarry Smith     ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr);
4686bf464f9SBarry Smith   }
469f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4701ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
471dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n);CHKERRQ(ierr);
4723a40ed3dSBarry Smith   PetscFunctionReturn(0);
473da3a660dSBarry Smith }
47467e560aaSBarry Smith 
475e0877f53SBarry Smith static PetscErrorCode MatSolveTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
476da3a660dSBarry Smith {
477c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
4786849ba73SBarry Smith   PetscErrorCode    ierr;
479f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
480f1ceaac6SMatthew G. Knepley   PetscScalar       *y,sone = 1.0;
48189ae1891SBarry Smith   Vec               tmp = NULL;
482c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
48367e560aaSBarry Smith 
4843a40ed3dSBarry Smith   PetscFunctionBegin;
485c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
486d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
487f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4881ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
489da3a660dSBarry Smith   if (yy == zz) {
49078b31e54SBarry Smith     ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr);
4913bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)tmp);CHKERRQ(ierr);
49278b31e54SBarry Smith     ierr = VecCopy(yy,tmp);CHKERRQ(ierr);
493da3a660dSBarry Smith   }
494d0f46423SBarry Smith   ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
495752f5567SLois Curfman McInnes   /* assume if pivots exist then use LU; else Cholesky */
496da3a660dSBarry Smith   if (mat->pivots) {
497ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
498e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
499ae7cfcebSSatish Balay #else
5008b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
501e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad solve");
502ae7cfcebSSatish Balay #endif
5033a40ed3dSBarry Smith   } else {
504ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
505e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
506ae7cfcebSSatish Balay #else
5078b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
508e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad solve");
509ae7cfcebSSatish Balay #endif
510da3a660dSBarry Smith   }
51190f02eecSBarry Smith   if (tmp) {
5122dcb1b2aSMatthew Knepley     ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr);
5136bf464f9SBarry Smith     ierr = VecDestroy(&tmp);CHKERRQ(ierr);
5143a40ed3dSBarry Smith   } else {
5152dcb1b2aSMatthew Knepley     ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr);
51690f02eecSBarry Smith   }
517f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5181ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
519dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n);CHKERRQ(ierr);
5203a40ed3dSBarry Smith   PetscFunctionReturn(0);
521da3a660dSBarry Smith }
522db4efbfdSBarry Smith 
523db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
524db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
525db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
526e0877f53SBarry Smith static PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
527db4efbfdSBarry Smith {
528db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_GETRF)
529db4efbfdSBarry Smith   PetscFunctionBegin;
530e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRF - Lapack routine is unavailable.");
531db4efbfdSBarry Smith #else
532db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
533db4efbfdSBarry Smith   PetscErrorCode ierr;
534db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
535db4efbfdSBarry Smith 
536db4efbfdSBarry Smith   PetscFunctionBegin;
537c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
538c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
539db4efbfdSBarry Smith   if (!mat->pivots) {
540854ce69bSBarry Smith     ierr = PetscMalloc1(A->rmap->n+1,&mat->pivots);CHKERRQ(ierr);
5413bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
542db4efbfdSBarry Smith   }
543db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
5448e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5458b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
5468e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
5478e57ea43SSatish Balay 
548e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
549e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
550db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
551db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
552db4efbfdSBarry Smith   A->ops->solveadd          = MatSolveAdd_SeqDense;
553db4efbfdSBarry Smith   A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
554d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
555db4efbfdSBarry Smith 
556f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
557f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
558f6224b95SHong Zhang 
559dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
560db4efbfdSBarry Smith #endif
561db4efbfdSBarry Smith   PetscFunctionReturn(0);
562db4efbfdSBarry Smith }
563db4efbfdSBarry Smith 
564e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
565db4efbfdSBarry Smith {
566db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_POTRF)
567db4efbfdSBarry Smith   PetscFunctionBegin;
568e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF - Lapack routine is unavailable.");
569db4efbfdSBarry Smith #else
570db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
571db4efbfdSBarry Smith   PetscErrorCode ierr;
572c5df96a5SBarry Smith   PetscBLASInt   info,n;
573db4efbfdSBarry Smith 
574db4efbfdSBarry Smith   PetscFunctionBegin;
575c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
576db4efbfdSBarry Smith   ierr = PetscFree(mat->pivots);CHKERRQ(ierr);
577db4efbfdSBarry Smith 
578db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
5798b83055fSJed Brown   PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
580e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
581db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
582db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
583db4efbfdSBarry Smith   A->ops->solveadd          = MatSolveAdd_SeqDense;
584db4efbfdSBarry Smith   A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
585d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
5862205254eSKarl Rupp 
587f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
588f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
589f6224b95SHong Zhang 
590eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
591db4efbfdSBarry Smith #endif
592db4efbfdSBarry Smith   PetscFunctionReturn(0);
593db4efbfdSBarry Smith }
594db4efbfdSBarry Smith 
595db4efbfdSBarry Smith 
5960481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
597db4efbfdSBarry Smith {
598db4efbfdSBarry Smith   PetscErrorCode ierr;
599db4efbfdSBarry Smith   MatFactorInfo  info;
600db4efbfdSBarry Smith 
601db4efbfdSBarry Smith   PetscFunctionBegin;
602db4efbfdSBarry Smith   info.fill = 1.0;
6032205254eSKarl Rupp 
604c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
605719d5645SBarry Smith   ierr = MatCholeskyFactor_SeqDense(fact,0,&info);CHKERRQ(ierr);
606db4efbfdSBarry Smith   PetscFunctionReturn(0);
607db4efbfdSBarry Smith }
608db4efbfdSBarry Smith 
609e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
610db4efbfdSBarry Smith {
611db4efbfdSBarry Smith   PetscFunctionBegin;
612c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
6131bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
614719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
615db4efbfdSBarry Smith   PetscFunctionReturn(0);
616db4efbfdSBarry Smith }
617db4efbfdSBarry Smith 
618e0877f53SBarry Smith static PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
619db4efbfdSBarry Smith {
620db4efbfdSBarry Smith   PetscFunctionBegin;
621b66fe19dSMatthew G Knepley   fact->preallocated         = PETSC_TRUE;
622c3ef05f6SHong Zhang   fact->assembled            = PETSC_TRUE;
623719d5645SBarry Smith   fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense;
624db4efbfdSBarry Smith   PetscFunctionReturn(0);
625db4efbfdSBarry Smith }
626db4efbfdSBarry Smith 
627cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
628db4efbfdSBarry Smith {
629db4efbfdSBarry Smith   PetscErrorCode ierr;
630db4efbfdSBarry Smith 
631db4efbfdSBarry Smith   PetscFunctionBegin;
632ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
633db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
634db4efbfdSBarry Smith   ierr = MatSetType(*fact,((PetscObject)A)->type_name);CHKERRQ(ierr);
635db4efbfdSBarry Smith   if (ftype == MAT_FACTOR_LU) {
636db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
637db4efbfdSBarry Smith   } else {
638db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
639db4efbfdSBarry Smith   }
640d5f3da31SBarry Smith   (*fact)->factortype = ftype;
64100c67f3bSHong Zhang 
64200c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
64300c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
644db4efbfdSBarry Smith   PetscFunctionReturn(0);
645db4efbfdSBarry Smith }
646db4efbfdSBarry Smith 
647289bc588SBarry Smith /* ------------------------------------------------------------------*/
648e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
649289bc588SBarry Smith {
650c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
651d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
652d9ca1df4SBarry Smith   const PetscScalar *b;
653dfbe8321SBarry Smith   PetscErrorCode    ierr;
654d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
655c5df96a5SBarry Smith   PetscBLASInt      o = 1,bm;
656289bc588SBarry Smith 
6573a40ed3dSBarry Smith   PetscFunctionBegin;
658422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
659c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
660289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
66171044d3cSBarry Smith     /* this is a hack fix, should have another version without the second BLASdot */
6622dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
663289bc588SBarry Smith   }
6641ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
665d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
666b965ef7fSBarry Smith   its  = its*lits;
667e32f2f54SBarry 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);
668289bc588SBarry Smith   while (its--) {
669fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
670289bc588SBarry Smith       for (i=0; i<m; i++) {
6718b83055fSJed Brown         PetscStackCallBLAS("BLASdot",xt   = b[i] - BLASdot_(&bm,v+i,&bm,x,&o));
67255a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
673289bc588SBarry Smith       }
674289bc588SBarry Smith     }
675fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
676289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
6778b83055fSJed Brown         PetscStackCallBLAS("BLASdot",xt   = b[i] - BLASdot_(&bm,v+i,&bm,x,&o));
67855a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
679289bc588SBarry Smith       }
680289bc588SBarry Smith     }
681289bc588SBarry Smith   }
682d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
6831ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
6843a40ed3dSBarry Smith   PetscFunctionReturn(0);
685289bc588SBarry Smith }
686289bc588SBarry Smith 
687289bc588SBarry Smith /* -----------------------------------------------------------------*/
688cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
689289bc588SBarry Smith {
690c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
691d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
692d9ca1df4SBarry Smith   PetscScalar       *y;
693dfbe8321SBarry Smith   PetscErrorCode    ierr;
6940805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
695ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
6963a40ed3dSBarry Smith 
6973a40ed3dSBarry Smith   PetscFunctionBegin;
698c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
699c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
700d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
701d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
7021ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
7038b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
704d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
7051ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
706dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
7073a40ed3dSBarry Smith   PetscFunctionReturn(0);
708289bc588SBarry Smith }
709800995b7SMatthew Knepley 
710cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
711289bc588SBarry Smith {
712c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
713d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
714dfbe8321SBarry Smith   PetscErrorCode    ierr;
7150805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
716d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
7173a40ed3dSBarry Smith 
7183a40ed3dSBarry Smith   PetscFunctionBegin;
719c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
720c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
721d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
722d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
7231ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
7248b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
725d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
7261ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
727dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
7283a40ed3dSBarry Smith   PetscFunctionReturn(0);
729289bc588SBarry Smith }
7306ee01492SSatish Balay 
731cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
732289bc588SBarry Smith {
733c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
734d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
735d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
736dfbe8321SBarry Smith   PetscErrorCode    ierr;
7370805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
7383a40ed3dSBarry Smith 
7393a40ed3dSBarry Smith   PetscFunctionBegin;
740c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
741c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
742d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
743600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
744d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
7451ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
7468b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
747d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
7481ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
749dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
7503a40ed3dSBarry Smith   PetscFunctionReturn(0);
751289bc588SBarry Smith }
7526ee01492SSatish Balay 
753e0877f53SBarry Smith static PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
754289bc588SBarry Smith {
755c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
756d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
757d9ca1df4SBarry Smith   PetscScalar       *y;
758dfbe8321SBarry Smith   PetscErrorCode    ierr;
7590805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
76087828ca2SBarry Smith   PetscScalar       _DOne=1.0;
7613a40ed3dSBarry Smith 
7623a40ed3dSBarry Smith   PetscFunctionBegin;
763c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
764c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
765d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
766600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
767d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
7681ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
7698b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
770d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
7711ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
772dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
7733a40ed3dSBarry Smith   PetscFunctionReturn(0);
774289bc588SBarry Smith }
775289bc588SBarry Smith 
776289bc588SBarry Smith /* -----------------------------------------------------------------*/
777e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
778289bc588SBarry Smith {
779c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
78087828ca2SBarry Smith   PetscScalar    *v;
7816849ba73SBarry Smith   PetscErrorCode ierr;
78213f74950SBarry Smith   PetscInt       i;
78367e560aaSBarry Smith 
7843a40ed3dSBarry Smith   PetscFunctionBegin;
785d0f46423SBarry Smith   *ncols = A->cmap->n;
786289bc588SBarry Smith   if (cols) {
787854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
788d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
789289bc588SBarry Smith   }
790289bc588SBarry Smith   if (vals) {
791854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
792289bc588SBarry Smith     v    = mat->v + row;
793d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
794289bc588SBarry Smith   }
7953a40ed3dSBarry Smith   PetscFunctionReturn(0);
796289bc588SBarry Smith }
7976ee01492SSatish Balay 
798e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
799289bc588SBarry Smith {
800dfbe8321SBarry Smith   PetscErrorCode ierr;
8016e111a19SKarl Rupp 
802606d414cSSatish Balay   PetscFunctionBegin;
803606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
804606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
8053a40ed3dSBarry Smith   PetscFunctionReturn(0);
806289bc588SBarry Smith }
807289bc588SBarry Smith /* ----------------------------------------------------------------*/
808e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
809289bc588SBarry Smith {
810c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
81113f74950SBarry Smith   PetscInt     i,j,idx=0;
812d6dfbf8fSBarry Smith 
8133a40ed3dSBarry Smith   PetscFunctionBegin;
814289bc588SBarry Smith   if (!mat->roworiented) {
815dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
816289bc588SBarry Smith       for (j=0; j<n; j++) {
817cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
8182515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
819e32f2f54SBarry Smith         if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
82058804f6dSBarry Smith #endif
821289bc588SBarry Smith         for (i=0; i<m; i++) {
822cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
8232515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
824e32f2f54SBarry 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);
82558804f6dSBarry Smith #endif
826cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
827289bc588SBarry Smith         }
828289bc588SBarry Smith       }
8293a40ed3dSBarry Smith     } else {
830289bc588SBarry Smith       for (j=0; j<n; j++) {
831cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
8322515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
833e32f2f54SBarry Smith         if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
83458804f6dSBarry Smith #endif
835289bc588SBarry Smith         for (i=0; i<m; i++) {
836cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
8372515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
838e32f2f54SBarry 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);
83958804f6dSBarry Smith #endif
840cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
841289bc588SBarry Smith         }
842289bc588SBarry Smith       }
843289bc588SBarry Smith     }
8443a40ed3dSBarry Smith   } else {
845dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
846e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
847cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
8482515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
849e32f2f54SBarry 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);
85058804f6dSBarry Smith #endif
851e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
852cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
8532515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
854e32f2f54SBarry 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);
85558804f6dSBarry Smith #endif
856cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
857e8d4e0b9SBarry Smith         }
858e8d4e0b9SBarry Smith       }
8593a40ed3dSBarry Smith     } else {
860289bc588SBarry Smith       for (i=0; i<m; i++) {
861cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
8622515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
863e32f2f54SBarry 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);
86458804f6dSBarry Smith #endif
865289bc588SBarry Smith         for (j=0; j<n; j++) {
866cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
8672515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
868e32f2f54SBarry 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);
86958804f6dSBarry Smith #endif
870cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
871289bc588SBarry Smith         }
872289bc588SBarry Smith       }
873289bc588SBarry Smith     }
874e8d4e0b9SBarry Smith   }
8753a40ed3dSBarry Smith   PetscFunctionReturn(0);
876289bc588SBarry Smith }
877e8d4e0b9SBarry Smith 
878e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
879ae80bb75SLois Curfman McInnes {
880ae80bb75SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
88113f74950SBarry Smith   PetscInt     i,j;
882ae80bb75SLois Curfman McInnes 
8833a40ed3dSBarry Smith   PetscFunctionBegin;
884ae80bb75SLois Curfman McInnes   /* row-oriented output */
885ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
88697e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
887e32f2f54SBarry 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);
888ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
8896f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
890e32f2f54SBarry 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);
89197e567efSBarry Smith       *v++ = mat->v[indexn[j]*mat->lda + indexm[i]];
892ae80bb75SLois Curfman McInnes     }
893ae80bb75SLois Curfman McInnes   }
8943a40ed3dSBarry Smith   PetscFunctionReturn(0);
895ae80bb75SLois Curfman McInnes }
896ae80bb75SLois Curfman McInnes 
897289bc588SBarry Smith /* -----------------------------------------------------------------*/
898289bc588SBarry Smith 
899e0877f53SBarry Smith static PetscErrorCode MatLoad_SeqDense(Mat newmat,PetscViewer viewer)
900aabbc4fbSShri Abhyankar {
901aabbc4fbSShri Abhyankar   Mat_SeqDense   *a;
902aabbc4fbSShri Abhyankar   PetscErrorCode ierr;
903aabbc4fbSShri Abhyankar   PetscInt       *scols,i,j,nz,header[4];
904aabbc4fbSShri Abhyankar   int            fd;
905aabbc4fbSShri Abhyankar   PetscMPIInt    size;
906aabbc4fbSShri Abhyankar   PetscInt       *rowlengths = 0,M,N,*cols,grows,gcols;
907aabbc4fbSShri Abhyankar   PetscScalar    *vals,*svals,*v,*w;
908ce94432eSBarry Smith   MPI_Comm       comm;
909aabbc4fbSShri Abhyankar 
910aabbc4fbSShri Abhyankar   PetscFunctionBegin;
911c98fd787SBarry Smith   /* force binary viewer to load .info file if it has not yet done so */
912c98fd787SBarry Smith   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
913ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
914aabbc4fbSShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
915aabbc4fbSShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"view must have one processor");
916aabbc4fbSShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
917aabbc4fbSShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
918aabbc4fbSShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not matrix object");
919aabbc4fbSShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
920aabbc4fbSShri Abhyankar 
921aabbc4fbSShri Abhyankar   /* set global size if not set already*/
922aabbc4fbSShri Abhyankar   if (newmat->rmap->n < 0 && newmat->rmap->N < 0 && newmat->cmap->n < 0 && newmat->cmap->N < 0) {
923aabbc4fbSShri Abhyankar     ierr = MatSetSizes(newmat,M,N,M,N);CHKERRQ(ierr);
924aabbc4fbSShri Abhyankar   } else {
925aabbc4fbSShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
926aabbc4fbSShri Abhyankar     ierr = MatGetSize(newmat,&grows,&gcols);CHKERRQ(ierr);
927aabbc4fbSShri 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);
928aabbc4fbSShri Abhyankar   }
929e6324fbbSBarry Smith   a = (Mat_SeqDense*)newmat->data;
930e6324fbbSBarry Smith   if (!a->user_alloc) {
9310298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
932e6324fbbSBarry Smith   }
933aabbc4fbSShri Abhyankar 
934aabbc4fbSShri Abhyankar   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense */
935aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
936aabbc4fbSShri Abhyankar     v = a->v;
937aabbc4fbSShri Abhyankar     /* Allocate some temp space to read in the values and then flip them
938aabbc4fbSShri Abhyankar        from row major to column major */
939854ce69bSBarry Smith     ierr = PetscMalloc1(M*N > 0 ? M*N : 1,&w);CHKERRQ(ierr);
940aabbc4fbSShri Abhyankar     /* read in nonzero values */
941aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,w,M*N,PETSC_SCALAR);CHKERRQ(ierr);
942aabbc4fbSShri Abhyankar     /* now flip the values and store them in the matrix*/
943aabbc4fbSShri Abhyankar     for (j=0; j<N; j++) {
944aabbc4fbSShri Abhyankar       for (i=0; i<M; i++) {
945aabbc4fbSShri Abhyankar         *v++ =w[i*N+j];
946aabbc4fbSShri Abhyankar       }
947aabbc4fbSShri Abhyankar     }
948aabbc4fbSShri Abhyankar     ierr = PetscFree(w);CHKERRQ(ierr);
949aabbc4fbSShri Abhyankar   } else {
950aabbc4fbSShri Abhyankar     /* read row lengths */
951854ce69bSBarry Smith     ierr = PetscMalloc1(M+1,&rowlengths);CHKERRQ(ierr);
952aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
953aabbc4fbSShri Abhyankar 
954aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
955aabbc4fbSShri Abhyankar     v = a->v;
956aabbc4fbSShri Abhyankar 
957aabbc4fbSShri Abhyankar     /* read column indices and nonzeros */
958854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&scols);CHKERRQ(ierr);
959aabbc4fbSShri Abhyankar     cols = scols;
960aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT);CHKERRQ(ierr);
961854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&svals);CHKERRQ(ierr);
962aabbc4fbSShri Abhyankar     vals = svals;
963aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR);CHKERRQ(ierr);
964aabbc4fbSShri Abhyankar 
965aabbc4fbSShri Abhyankar     /* insert into matrix */
966aabbc4fbSShri Abhyankar     for (i=0; i<M; i++) {
967aabbc4fbSShri Abhyankar       for (j=0; j<rowlengths[i]; j++) v[i+M*scols[j]] = svals[j];
968aabbc4fbSShri Abhyankar       svals += rowlengths[i]; scols += rowlengths[i];
969aabbc4fbSShri Abhyankar     }
970aabbc4fbSShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
971aabbc4fbSShri Abhyankar     ierr = PetscFree(cols);CHKERRQ(ierr);
972aabbc4fbSShri Abhyankar     ierr = PetscFree(rowlengths);CHKERRQ(ierr);
973aabbc4fbSShri Abhyankar   }
974aabbc4fbSShri Abhyankar   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
975aabbc4fbSShri Abhyankar   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
976aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
977aabbc4fbSShri Abhyankar }
978aabbc4fbSShri Abhyankar 
9796849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
980289bc588SBarry Smith {
981932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
982dfbe8321SBarry Smith   PetscErrorCode    ierr;
98313f74950SBarry Smith   PetscInt          i,j;
9842dcb1b2aSMatthew Knepley   const char        *name;
98587828ca2SBarry Smith   PetscScalar       *v;
986f3ef73ceSBarry Smith   PetscViewerFormat format;
9875f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
988ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
9895f481a85SSatish Balay #endif
990932b0c3eSLois Curfman McInnes 
9913a40ed3dSBarry Smith   PetscFunctionBegin;
992b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
993456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
9943a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
995fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
996d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
997d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
99844cd7ae7SLois Curfman McInnes       v    = a->v + i;
99977431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1000d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1001aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1002329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
100357622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1004329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
100557622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
10066831982aSBarry Smith         }
100780cd9d93SLois Curfman McInnes #else
10086831982aSBarry Smith         if (*v) {
100957622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
10106831982aSBarry Smith         }
101180cd9d93SLois Curfman McInnes #endif
10121b807ce4Svictorle         v += a->lda;
101380cd9d93SLois Curfman McInnes       }
1014b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
101580cd9d93SLois Curfman McInnes     }
1016d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
10173a40ed3dSBarry Smith   } else {
1018d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1019aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
102047989497SBarry Smith     /* determine if matrix has all real values */
102147989497SBarry Smith     v = a->v;
1022d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1023ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
102447989497SBarry Smith     }
102547989497SBarry Smith #endif
1026fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
10273a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1028d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1029d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1030fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1031ffac6cdbSBarry Smith     }
1032ffac6cdbSBarry Smith 
1033d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1034932b0c3eSLois Curfman McInnes       v = a->v + i;
1035d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1036aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
103747989497SBarry Smith         if (allreal) {
1038c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
103947989497SBarry Smith         } else {
1040c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
104147989497SBarry Smith         }
1042289bc588SBarry Smith #else
1043c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1044289bc588SBarry Smith #endif
10451b807ce4Svictorle         v += a->lda;
1046289bc588SBarry Smith       }
1047b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1048289bc588SBarry Smith     }
1049fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1050b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1051ffac6cdbSBarry Smith     }
1052d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1053da3a660dSBarry Smith   }
1054b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
10553a40ed3dSBarry Smith   PetscFunctionReturn(0);
1056289bc588SBarry Smith }
1057289bc588SBarry Smith 
10586849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_Binary(Mat A,PetscViewer viewer)
1059932b0c3eSLois Curfman McInnes {
1060932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
10616849ba73SBarry Smith   PetscErrorCode    ierr;
106213f74950SBarry Smith   int               fd;
1063d0f46423SBarry Smith   PetscInt          ict,j,n = A->cmap->n,m = A->rmap->n,i,*col_lens,nz = m*n;
1064f4403165SShri Abhyankar   PetscScalar       *v,*anonz,*vals;
1065f4403165SShri Abhyankar   PetscViewerFormat format;
1066932b0c3eSLois Curfman McInnes 
10673a40ed3dSBarry Smith   PetscFunctionBegin;
1068b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
106990ace30eSBarry Smith 
1070f4403165SShri Abhyankar   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1071f4403165SShri Abhyankar   if (format == PETSC_VIEWER_NATIVE) {
1072f4403165SShri Abhyankar     /* store the matrix as a dense matrix */
1073785e854fSJed Brown     ierr = PetscMalloc1(4,&col_lens);CHKERRQ(ierr);
10742205254eSKarl Rupp 
1075f4403165SShri Abhyankar     col_lens[0] = MAT_FILE_CLASSID;
1076f4403165SShri Abhyankar     col_lens[1] = m;
1077f4403165SShri Abhyankar     col_lens[2] = n;
1078f4403165SShri Abhyankar     col_lens[3] = MATRIX_BINARY_FORMAT_DENSE;
10792205254eSKarl Rupp 
1080f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,col_lens,4,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1081f4403165SShri Abhyankar     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1082f4403165SShri Abhyankar 
1083f4403165SShri Abhyankar     /* write out matrix, by rows */
1084854ce69bSBarry Smith     ierr = PetscMalloc1(m*n+1,&vals);CHKERRQ(ierr);
1085f4403165SShri Abhyankar     v    = a->v;
1086f4403165SShri Abhyankar     for (j=0; j<n; j++) {
1087f4403165SShri Abhyankar       for (i=0; i<m; i++) {
1088f4403165SShri Abhyankar         vals[j + i*n] = *v++;
1089f4403165SShri Abhyankar       }
1090f4403165SShri Abhyankar     }
1091f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,vals,n*m,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1092f4403165SShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1093f4403165SShri Abhyankar   } else {
1094854ce69bSBarry Smith     ierr = PetscMalloc1(4+nz,&col_lens);CHKERRQ(ierr);
10952205254eSKarl Rupp 
10960700a824SBarry Smith     col_lens[0] = MAT_FILE_CLASSID;
1097932b0c3eSLois Curfman McInnes     col_lens[1] = m;
1098932b0c3eSLois Curfman McInnes     col_lens[2] = n;
1099932b0c3eSLois Curfman McInnes     col_lens[3] = nz;
1100932b0c3eSLois Curfman McInnes 
1101932b0c3eSLois Curfman McInnes     /* store lengths of each row and write (including header) to file */
1102932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) col_lens[4+i] = n;
11036f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,4+m,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1104932b0c3eSLois Curfman McInnes 
1105932b0c3eSLois Curfman McInnes     /* Possibly should write in smaller increments, not whole matrix at once? */
1106932b0c3eSLois Curfman McInnes     /* store column indices (zero start index) */
1107932b0c3eSLois Curfman McInnes     ict = 0;
1108932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1109932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) col_lens[ict++] = j;
1110932b0c3eSLois Curfman McInnes     }
11116f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
1112606d414cSSatish Balay     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1113932b0c3eSLois Curfman McInnes 
1114932b0c3eSLois Curfman McInnes     /* store nonzero values */
1115854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&anonz);CHKERRQ(ierr);
1116932b0c3eSLois Curfman McInnes     ict  = 0;
1117932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1118932b0c3eSLois Curfman McInnes       v = a->v + i;
1119932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) {
11201b807ce4Svictorle         anonz[ict++] = *v; v += a->lda;
1121932b0c3eSLois Curfman McInnes       }
1122932b0c3eSLois Curfman McInnes     }
11236f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,anonz,nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1124606d414cSSatish Balay     ierr = PetscFree(anonz);CHKERRQ(ierr);
1125f4403165SShri Abhyankar   }
11263a40ed3dSBarry Smith   PetscFunctionReturn(0);
1127932b0c3eSLois Curfman McInnes }
1128932b0c3eSLois Curfman McInnes 
11299804daf3SBarry Smith #include <petscdraw.h>
1130e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1131f1af5d2fSBarry Smith {
1132f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
1133f1af5d2fSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
11346849ba73SBarry Smith   PetscErrorCode    ierr;
1135383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1136383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
113787828ca2SBarry Smith   PetscScalar       *v = a->v;
1138b0a32e0cSBarry Smith   PetscViewer       viewer;
1139b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1140f3ef73ceSBarry Smith   PetscViewerFormat format;
1141f1af5d2fSBarry Smith 
1142f1af5d2fSBarry Smith   PetscFunctionBegin;
1143f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1144b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1145b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1146f1af5d2fSBarry Smith 
1147f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1148383922c3SLisandro Dalcin 
1149fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1150383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1151f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1152f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1153383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1154f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1155f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1156f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1157329f5518SBarry Smith         if (PetscRealPart(v[j*m+i]) >  0.) {
1158b0a32e0cSBarry Smith           color = PETSC_DRAW_RED;
1159329f5518SBarry Smith         } else if (PetscRealPart(v[j*m+i]) <  0.) {
1160b0a32e0cSBarry Smith           color = PETSC_DRAW_BLUE;
1161f1af5d2fSBarry Smith         } else {
1162f1af5d2fSBarry Smith           continue;
1163f1af5d2fSBarry Smith         }
1164b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1165f1af5d2fSBarry Smith       }
1166f1af5d2fSBarry Smith     }
1167383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1168f1af5d2fSBarry Smith   } else {
1169f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1170f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1171b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1172b05fc000SLisandro Dalcin     PetscDraw popup;
1173b05fc000SLisandro Dalcin 
1174f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1175f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1176f1af5d2fSBarry Smith     }
1177383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1178b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
117945f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1180383922c3SLisandro Dalcin 
1181383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1182f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1183f1af5d2fSBarry Smith       x_l = j;
1184f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1185f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1186f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1187f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1188b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1189b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1190f1af5d2fSBarry Smith       }
1191f1af5d2fSBarry Smith     }
1192383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1193f1af5d2fSBarry Smith   }
1194f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1195f1af5d2fSBarry Smith }
1196f1af5d2fSBarry Smith 
1197e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1198f1af5d2fSBarry Smith {
1199b0a32e0cSBarry Smith   PetscDraw      draw;
1200ace3abfcSBarry Smith   PetscBool      isnull;
1201329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1202dfbe8321SBarry Smith   PetscErrorCode ierr;
1203f1af5d2fSBarry Smith 
1204f1af5d2fSBarry Smith   PetscFunctionBegin;
1205b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1206b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1207abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1208f1af5d2fSBarry Smith 
1209d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1210f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1211b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1212832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1213b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
12140298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1215832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1216f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1217f1af5d2fSBarry Smith }
1218f1af5d2fSBarry Smith 
1219dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1220932b0c3eSLois Curfman McInnes {
1221dfbe8321SBarry Smith   PetscErrorCode ierr;
1222ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1223932b0c3eSLois Curfman McInnes 
12243a40ed3dSBarry Smith   PetscFunctionBegin;
1225251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1226251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1227251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
12280f5bd95cSBarry Smith 
1229c45a1595SBarry Smith   if (iascii) {
1230c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
12310f5bd95cSBarry Smith   } else if (isbinary) {
12323a40ed3dSBarry Smith     ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr);
1233f1af5d2fSBarry Smith   } else if (isdraw) {
1234f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1235932b0c3eSLois Curfman McInnes   }
12363a40ed3dSBarry Smith   PetscFunctionReturn(0);
1237932b0c3eSLois Curfman McInnes }
1238289bc588SBarry Smith 
1239*d3042a70SBarry Smith static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar array[])
1240*d3042a70SBarry Smith {
1241*d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1242*d3042a70SBarry Smith 
1243*d3042a70SBarry Smith   PetscFunctionBegin;
1244*d3042a70SBarry Smith   a->unplacedarray       = a->v;
1245*d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1246*d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1247*d3042a70SBarry Smith   PetscFunctionReturn(0);
1248*d3042a70SBarry Smith }
1249*d3042a70SBarry Smith 
1250*d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1251*d3042a70SBarry Smith {
1252*d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1253*d3042a70SBarry Smith 
1254*d3042a70SBarry Smith   PetscFunctionBegin;
1255*d3042a70SBarry Smith   a->v             = a->unplacedarray;
1256*d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1257*d3042a70SBarry Smith   a->unplacedarray = NULL;
1258*d3042a70SBarry Smith   PetscFunctionReturn(0);
1259*d3042a70SBarry Smith }
1260*d3042a70SBarry Smith 
1261e0877f53SBarry Smith static PetscErrorCode MatDestroy_SeqDense(Mat mat)
1262289bc588SBarry Smith {
1263ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1264dfbe8321SBarry Smith   PetscErrorCode ierr;
126590f02eecSBarry Smith 
12663a40ed3dSBarry Smith   PetscFunctionBegin;
1267aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1268d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1269a5a9c739SBarry Smith #endif
127005b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1271abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
12726857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1273bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1274dbd8c25aSHong Zhang 
1275dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
1276bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
1277*d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1278*d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
1279bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
12808baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
12818baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
12828baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
12838baccfbdSHong Zhang #endif
1284bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
1285bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1286bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1287bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1288abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatPtAP_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
12893bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
12903bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
12913bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
12923a40ed3dSBarry Smith   PetscFunctionReturn(0);
1293289bc588SBarry Smith }
1294289bc588SBarry Smith 
1295e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1296289bc588SBarry Smith {
1297c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
12986849ba73SBarry Smith   PetscErrorCode ierr;
129913f74950SBarry Smith   PetscInt       k,j,m,n,M;
130087828ca2SBarry Smith   PetscScalar    *v,tmp;
130148b35521SBarry Smith 
13023a40ed3dSBarry Smith   PetscFunctionBegin;
1303d0f46423SBarry Smith   v = mat->v; m = A->rmap->n; M = mat->lda; n = A->cmap->n;
1304cf37664fSBarry Smith   if (reuse == MAT_INPLACE_MATRIX) { /* in place transpose */
1305e7e72b3dSBarry Smith     if (m != n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can not transpose non-square matrix in place");
1306e7e72b3dSBarry Smith     else {
1307d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1308289bc588SBarry Smith         for (k=0; k<j; k++) {
13091b807ce4Svictorle           tmp        = v[j + k*M];
13101b807ce4Svictorle           v[j + k*M] = v[k + j*M];
13111b807ce4Svictorle           v[k + j*M] = tmp;
1312289bc588SBarry Smith         }
1313289bc588SBarry Smith       }
1314d64ed03dSBarry Smith     }
13153a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1316d3e5ee88SLois Curfman McInnes     Mat          tmat;
1317ec8511deSBarry Smith     Mat_SeqDense *tmatd;
131887828ca2SBarry Smith     PetscScalar  *v2;
1319af36a384SStefano Zampini     PetscInt     M2;
1320ea709b57SSatish Balay 
1321fc4dec0aSBarry Smith     if (reuse == MAT_INITIAL_MATRIX) {
1322ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1323d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
13247adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
13250298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1326fc4dec0aSBarry Smith     } else {
1327fc4dec0aSBarry Smith       tmat = *matout;
1328fc4dec0aSBarry Smith     }
1329ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1330af36a384SStefano Zampini     v = mat->v; v2 = tmatd->v; M2 = tmatd->lda;
1331d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1332af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1333d3e5ee88SLois Curfman McInnes     }
13346d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
13356d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1336d3e5ee88SLois Curfman McInnes     *matout = tmat;
133748b35521SBarry Smith   }
13383a40ed3dSBarry Smith   PetscFunctionReturn(0);
1339289bc588SBarry Smith }
1340289bc588SBarry Smith 
1341e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1342289bc588SBarry Smith {
1343c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat1 = (Mat_SeqDense*)A1->data;
1344c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat2 = (Mat_SeqDense*)A2->data;
134513f74950SBarry Smith   PetscInt     i,j;
1346a2ea699eSBarry Smith   PetscScalar  *v1,*v2;
13479ea5d5aeSSatish Balay 
13483a40ed3dSBarry Smith   PetscFunctionBegin;
1349d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1350d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1351d0f46423SBarry Smith   for (i=0; i<A1->rmap->n; i++) {
13521b807ce4Svictorle     v1 = mat1->v+i; v2 = mat2->v+i;
1353d0f46423SBarry Smith     for (j=0; j<A1->cmap->n; j++) {
13543a40ed3dSBarry Smith       if (*v1 != *v2) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
13551b807ce4Svictorle       v1 += mat1->lda; v2 += mat2->lda;
13561b807ce4Svictorle     }
1357289bc588SBarry Smith   }
135877c4ece6SBarry Smith   *flg = PETSC_TRUE;
13593a40ed3dSBarry Smith   PetscFunctionReturn(0);
1360289bc588SBarry Smith }
1361289bc588SBarry Smith 
1362e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1363289bc588SBarry Smith {
1364c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
1365dfbe8321SBarry Smith   PetscErrorCode ierr;
136613f74950SBarry Smith   PetscInt       i,n,len;
136787828ca2SBarry Smith   PetscScalar    *x,zero = 0.0;
136844cd7ae7SLois Curfman McInnes 
13693a40ed3dSBarry Smith   PetscFunctionBegin;
13702dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
13717a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
13721ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1373d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1374e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
137544cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
13761b807ce4Svictorle     x[i] = mat->v[i*mat->lda + i];
1377289bc588SBarry Smith   }
13781ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
13793a40ed3dSBarry Smith   PetscFunctionReturn(0);
1380289bc588SBarry Smith }
1381289bc588SBarry Smith 
1382e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1383289bc588SBarry Smith {
1384c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1385f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1386f1ceaac6SMatthew G. Knepley   PetscScalar       x,*v;
1387dfbe8321SBarry Smith   PetscErrorCode    ierr;
1388d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
138955659b69SBarry Smith 
13903a40ed3dSBarry Smith   PetscFunctionBegin;
139128988994SBarry Smith   if (ll) {
13927a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1393f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1394e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1395da3a660dSBarry Smith     for (i=0; i<m; i++) {
1396da3a660dSBarry Smith       x = l[i];
1397da3a660dSBarry Smith       v = mat->v + i;
1398b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1399da3a660dSBarry Smith     }
1400f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1401eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1402da3a660dSBarry Smith   }
140328988994SBarry Smith   if (rr) {
14047a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1405f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1406e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1407da3a660dSBarry Smith     for (i=0; i<n; i++) {
1408da3a660dSBarry Smith       x = r[i];
1409b43bac26SStefano Zampini       v = mat->v + i*mat->lda;
14102205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1411da3a660dSBarry Smith     }
1412f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1413eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1414da3a660dSBarry Smith   }
14153a40ed3dSBarry Smith   PetscFunctionReturn(0);
1416289bc588SBarry Smith }
1417289bc588SBarry Smith 
1418e0877f53SBarry Smith static PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1419289bc588SBarry Smith {
1420c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
142187828ca2SBarry Smith   PetscScalar    *v   = mat->v;
1422329f5518SBarry Smith   PetscReal      sum  = 0.0;
1423d0f46423SBarry Smith   PetscInt       lda  =mat->lda,m=A->rmap->n,i,j;
1424efee365bSSatish Balay   PetscErrorCode ierr;
142555659b69SBarry Smith 
14263a40ed3dSBarry Smith   PetscFunctionBegin;
1427289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1428a5ce6ee0Svictorle     if (lda>m) {
1429d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1430a5ce6ee0Svictorle         v = mat->v+j*lda;
1431a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1432a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1433a5ce6ee0Svictorle         }
1434a5ce6ee0Svictorle       }
1435a5ce6ee0Svictorle     } else {
1436570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1437570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1438570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1439570b7f6dSBarry Smith     }
1440570b7f6dSBarry Smith #else
1441d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1442329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1443289bc588SBarry Smith       }
1444a5ce6ee0Svictorle     }
14458f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1446570b7f6dSBarry Smith #endif
1447dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
14483a40ed3dSBarry Smith   } else if (type == NORM_1) {
1449064f8208SBarry Smith     *nrm = 0.0;
1450d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
14511b807ce4Svictorle       v   = mat->v + j*mat->lda;
1452289bc588SBarry Smith       sum = 0.0;
1453d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
145433a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1455289bc588SBarry Smith       }
1456064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1457289bc588SBarry Smith     }
1458eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
14593a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1460064f8208SBarry Smith     *nrm = 0.0;
1461d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1462289bc588SBarry Smith       v   = mat->v + j;
1463289bc588SBarry Smith       sum = 0.0;
1464d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
14651b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1466289bc588SBarry Smith       }
1467064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1468289bc588SBarry Smith     }
1469eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1470e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
14713a40ed3dSBarry Smith   PetscFunctionReturn(0);
1472289bc588SBarry Smith }
1473289bc588SBarry Smith 
1474e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1475289bc588SBarry Smith {
1476c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
147763ba0a88SBarry Smith   PetscErrorCode ierr;
147867e560aaSBarry Smith 
14793a40ed3dSBarry Smith   PetscFunctionBegin;
1480b5a2b587SKris Buschelman   switch (op) {
1481b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
14824e0d8c25SBarry Smith     aij->roworiented = flg;
1483b5a2b587SKris Buschelman     break;
1484512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1485b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
14863971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
14874e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
148813fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1489b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1490b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
14915021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
14925021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
14935021d80fSJed Brown     break;
14945021d80fSJed Brown   case MAT_SPD:
149577e54ba9SKris Buschelman   case MAT_SYMMETRIC:
149677e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
14979a4540c5SBarry Smith   case MAT_HERMITIAN:
14989a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
14995021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
150077e54ba9SKris Buschelman     break;
1501b5a2b587SKris Buschelman   default:
1502e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
15033a40ed3dSBarry Smith   }
15043a40ed3dSBarry Smith   PetscFunctionReturn(0);
1505289bc588SBarry Smith }
1506289bc588SBarry Smith 
1507e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
15086f0a148fSBarry Smith {
1509ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
15106849ba73SBarry Smith   PetscErrorCode ierr;
1511d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
15123a40ed3dSBarry Smith 
15133a40ed3dSBarry Smith   PetscFunctionBegin;
1514a5ce6ee0Svictorle   if (lda>m) {
1515d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1516a5ce6ee0Svictorle       ierr = PetscMemzero(l->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr);
1517a5ce6ee0Svictorle     }
1518a5ce6ee0Svictorle   } else {
1519d0f46423SBarry Smith     ierr = PetscMemzero(l->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
1520a5ce6ee0Svictorle   }
15213a40ed3dSBarry Smith   PetscFunctionReturn(0);
15226f0a148fSBarry Smith }
15236f0a148fSBarry Smith 
1524e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
15256f0a148fSBarry Smith {
152697b48c8fSBarry Smith   PetscErrorCode    ierr;
1527ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1528b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
152997b48c8fSBarry Smith   PetscScalar       *slot,*bb;
153097b48c8fSBarry Smith   const PetscScalar *xx;
153155659b69SBarry Smith 
15323a40ed3dSBarry Smith   PetscFunctionBegin;
1533b9679d65SBarry Smith #if defined(PETSC_USE_DEBUG)
1534b9679d65SBarry Smith   for (i=0; i<N; i++) {
1535b9679d65SBarry Smith     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1536b9679d65SBarry 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);
1537b9679d65SBarry Smith   }
1538b9679d65SBarry Smith #endif
1539b9679d65SBarry Smith 
154097b48c8fSBarry Smith   /* fix right hand side if needed */
154197b48c8fSBarry Smith   if (x && b) {
154297b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
154397b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
15442205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
154597b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
154697b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
154797b48c8fSBarry Smith   }
154897b48c8fSBarry Smith 
15496f0a148fSBarry Smith   for (i=0; i<N; i++) {
15506f0a148fSBarry Smith     slot = l->v + rows[i];
1551b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
15526f0a148fSBarry Smith   }
1553f4df32b1SMatthew Knepley   if (diag != 0.0) {
1554b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
15556f0a148fSBarry Smith     for (i=0; i<N; i++) {
1556b9679d65SBarry Smith       slot  = l->v + (m+1)*rows[i];
1557f4df32b1SMatthew Knepley       *slot = diag;
15586f0a148fSBarry Smith     }
15596f0a148fSBarry Smith   }
15603a40ed3dSBarry Smith   PetscFunctionReturn(0);
15616f0a148fSBarry Smith }
1562557bce09SLois Curfman McInnes 
1563e0877f53SBarry Smith static PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar *array[])
156464e87e97SBarry Smith {
1565c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
15663a40ed3dSBarry Smith 
15673a40ed3dSBarry Smith   PetscFunctionBegin;
1568e32f2f54SBarry 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");
156964e87e97SBarry Smith   *array = mat->v;
15703a40ed3dSBarry Smith   PetscFunctionReturn(0);
157164e87e97SBarry Smith }
15720754003eSLois Curfman McInnes 
1573e0877f53SBarry Smith static PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar *array[])
1574ff14e315SSatish Balay {
15753a40ed3dSBarry Smith   PetscFunctionBegin;
157609b544d4SBarry Smith   *array = 0; /* user cannot accidently use the array later */
15773a40ed3dSBarry Smith   PetscFunctionReturn(0);
1578ff14e315SSatish Balay }
15790754003eSLois Curfman McInnes 
1580dec5eb66SMatthew G Knepley /*@C
15818c778c55SBarry Smith    MatDenseGetArray - gives access to the array where the data for a SeqDense matrix is stored
158273a71a0fSBarry Smith 
158373a71a0fSBarry Smith    Not Collective
158473a71a0fSBarry Smith 
158573a71a0fSBarry Smith    Input Parameter:
1586579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
158773a71a0fSBarry Smith 
158873a71a0fSBarry Smith    Output Parameter:
158973a71a0fSBarry Smith .   array - pointer to the data
159073a71a0fSBarry Smith 
159173a71a0fSBarry Smith    Level: intermediate
159273a71a0fSBarry Smith 
15938c778c55SBarry Smith .seealso: MatDenseRestoreArray()
159473a71a0fSBarry Smith @*/
15958c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
159673a71a0fSBarry Smith {
159773a71a0fSBarry Smith   PetscErrorCode ierr;
159873a71a0fSBarry Smith 
159973a71a0fSBarry Smith   PetscFunctionBegin;
16008c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
160173a71a0fSBarry Smith   PetscFunctionReturn(0);
160273a71a0fSBarry Smith }
160373a71a0fSBarry Smith 
1604dec5eb66SMatthew G Knepley /*@C
1605579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
160673a71a0fSBarry Smith 
160773a71a0fSBarry Smith    Not Collective
160873a71a0fSBarry Smith 
160973a71a0fSBarry Smith    Input Parameters:
1610579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
161173a71a0fSBarry Smith .  array - pointer to the data
161273a71a0fSBarry Smith 
161373a71a0fSBarry Smith    Level: intermediate
161473a71a0fSBarry Smith 
16158c778c55SBarry Smith .seealso: MatDenseGetArray()
161673a71a0fSBarry Smith @*/
16178c778c55SBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
161873a71a0fSBarry Smith {
161973a71a0fSBarry Smith   PetscErrorCode ierr;
162073a71a0fSBarry Smith 
162173a71a0fSBarry Smith   PetscFunctionBegin;
16228c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
162373a71a0fSBarry Smith   PetscFunctionReturn(0);
162473a71a0fSBarry Smith }
162573a71a0fSBarry Smith 
16267dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
16270754003eSLois Curfman McInnes {
1628c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
16296849ba73SBarry Smith   PetscErrorCode ierr;
16305d0c19d7SBarry Smith   PetscInt       i,j,nrows,ncols;
16315d0c19d7SBarry Smith   const PetscInt *irow,*icol;
163287828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
16330754003eSLois Curfman McInnes   Mat            newmat;
16340754003eSLois Curfman McInnes 
16353a40ed3dSBarry Smith   PetscFunctionBegin;
163678b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
163778b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1638e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1639e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
16400754003eSLois Curfman McInnes 
1641182d2002SSatish Balay   /* Check submatrixcall */
1642182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
164313f74950SBarry Smith     PetscInt n_cols,n_rows;
1644182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
164521a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
1646f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
1647c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
164821a2c019SBarry Smith     }
1649182d2002SSatish Balay     newmat = *B;
1650182d2002SSatish Balay   } else {
16510754003eSLois Curfman McInnes     /* Create and fill new matrix */
1652ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
1653f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
16547adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
16550298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1656182d2002SSatish Balay   }
1657182d2002SSatish Balay 
1658182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1659182d2002SSatish Balay   bv = ((Mat_SeqDense*)newmat->data)->v;
1660182d2002SSatish Balay 
1661182d2002SSatish Balay   for (i=0; i<ncols; i++) {
16626de62eeeSBarry Smith     av = v + mat->lda*icol[i];
16632205254eSKarl Rupp     for (j=0; j<nrows; j++) *bv++ = av[irow[j]];
16640754003eSLois Curfman McInnes   }
1665182d2002SSatish Balay 
1666182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
16676d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16686d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16690754003eSLois Curfman McInnes 
16700754003eSLois Curfman McInnes   /* Free work space */
167178b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
167278b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1673182d2002SSatish Balay   *B   = newmat;
16743a40ed3dSBarry Smith   PetscFunctionReturn(0);
16750754003eSLois Curfman McInnes }
16760754003eSLois Curfman McInnes 
16777dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1678905e6a2fSBarry Smith {
16796849ba73SBarry Smith   PetscErrorCode ierr;
168013f74950SBarry Smith   PetscInt       i;
1681905e6a2fSBarry Smith 
16823a40ed3dSBarry Smith   PetscFunctionBegin;
1683905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1684df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
1685905e6a2fSBarry Smith   }
1686905e6a2fSBarry Smith 
1687905e6a2fSBarry Smith   for (i=0; i<n; i++) {
16887dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1689905e6a2fSBarry Smith   }
16903a40ed3dSBarry Smith   PetscFunctionReturn(0);
1691905e6a2fSBarry Smith }
1692905e6a2fSBarry Smith 
1693e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
1694c0aa2d19SHong Zhang {
1695c0aa2d19SHong Zhang   PetscFunctionBegin;
1696c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1697c0aa2d19SHong Zhang }
1698c0aa2d19SHong Zhang 
1699e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
1700c0aa2d19SHong Zhang {
1701c0aa2d19SHong Zhang   PetscFunctionBegin;
1702c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1703c0aa2d19SHong Zhang }
1704c0aa2d19SHong Zhang 
1705e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
17064b0e389bSBarry Smith {
17074b0e389bSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
17086849ba73SBarry Smith   PetscErrorCode ierr;
1709d0f46423SBarry Smith   PetscInt       lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
17103a40ed3dSBarry Smith 
17113a40ed3dSBarry Smith   PetscFunctionBegin;
171233f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
171333f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
1714cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
17153a40ed3dSBarry Smith     PetscFunctionReturn(0);
17163a40ed3dSBarry Smith   }
1717e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
1718a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
17190dbb7854Svictorle     for (j=0; j<n; j++) {
1720a5ce6ee0Svictorle       ierr = PetscMemcpy(b->v+j*lda2,a->v+j*lda1,m*sizeof(PetscScalar));CHKERRQ(ierr);
1721a5ce6ee0Svictorle     }
1722a5ce6ee0Svictorle   } else {
1723d0f46423SBarry Smith     ierr = PetscMemcpy(b->v,a->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
1724a5ce6ee0Svictorle   }
1725273d9f13SBarry Smith   PetscFunctionReturn(0);
1726273d9f13SBarry Smith }
1727273d9f13SBarry Smith 
1728e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
1729273d9f13SBarry Smith {
1730dfbe8321SBarry Smith   PetscErrorCode ierr;
1731273d9f13SBarry Smith 
1732273d9f13SBarry Smith   PetscFunctionBegin;
1733273d9f13SBarry Smith   ierr =  MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
17343a40ed3dSBarry Smith   PetscFunctionReturn(0);
17354b0e389bSBarry Smith }
17364b0e389bSBarry Smith 
1737ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
1738ba337c44SJed Brown {
1739ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1740ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1741ba337c44SJed Brown   PetscScalar  *aa = a->v;
1742ba337c44SJed Brown 
1743ba337c44SJed Brown   PetscFunctionBegin;
1744ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
1745ba337c44SJed Brown   PetscFunctionReturn(0);
1746ba337c44SJed Brown }
1747ba337c44SJed Brown 
1748ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
1749ba337c44SJed Brown {
1750ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1751ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1752ba337c44SJed Brown   PetscScalar  *aa = a->v;
1753ba337c44SJed Brown 
1754ba337c44SJed Brown   PetscFunctionBegin;
1755ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
1756ba337c44SJed Brown   PetscFunctionReturn(0);
1757ba337c44SJed Brown }
1758ba337c44SJed Brown 
1759ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
1760ba337c44SJed Brown {
1761ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1762ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1763ba337c44SJed Brown   PetscScalar  *aa = a->v;
1764ba337c44SJed Brown 
1765ba337c44SJed Brown   PetscFunctionBegin;
1766ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1767ba337c44SJed Brown   PetscFunctionReturn(0);
1768ba337c44SJed Brown }
1769284134d9SBarry Smith 
1770a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
1771150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
1772a9fe9ddaSSatish Balay {
1773a9fe9ddaSSatish Balay   PetscErrorCode ierr;
1774a9fe9ddaSSatish Balay 
1775a9fe9ddaSSatish Balay   PetscFunctionBegin;
1776a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
17773ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
1778a9fe9ddaSSatish Balay     ierr = MatMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
17793ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
1780a9fe9ddaSSatish Balay   }
17813ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
1782a9fe9ddaSSatish Balay   ierr = MatMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
17833ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
1784a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1785a9fe9ddaSSatish Balay }
1786a9fe9ddaSSatish Balay 
1787a9fe9ddaSSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
1788a9fe9ddaSSatish Balay {
1789ee16a9a1SHong Zhang   PetscErrorCode ierr;
1790d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
1791ee16a9a1SHong Zhang   Mat            Cmat;
1792a9fe9ddaSSatish Balay 
1793ee16a9a1SHong Zhang   PetscFunctionBegin;
1794e32f2f54SBarry 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);
1795ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
1796ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
1797ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
17980298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
1799d73949e8SHong Zhang 
1800ee16a9a1SHong Zhang   *C = Cmat;
1801ee16a9a1SHong Zhang   PetscFunctionReturn(0);
1802ee16a9a1SHong Zhang }
1803a9fe9ddaSSatish Balay 
1804a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
1805a9fe9ddaSSatish Balay {
1806a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1807a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
1808a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
18090805154bSBarry Smith   PetscBLASInt   m,n,k;
1810a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
1811c5df96a5SBarry Smith   PetscErrorCode ierr;
1812fd4e9aacSBarry Smith   PetscBool      flg;
1813a9fe9ddaSSatish Balay 
1814a9fe9ddaSSatish Balay   PetscFunctionBegin;
1815fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQDENSE,&flg);CHKERRQ(ierr);
1816fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Second matrix must be dense");
1817fd4e9aacSBarry Smith 
1818fd4e9aacSBarry Smith   /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/
1819fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
1820fd4e9aacSBarry Smith   if (flg) {
1821fd4e9aacSBarry Smith     C->ops->matmultnumeric = MatMatMultNumeric_SeqAIJ_SeqDense;
1822fd4e9aacSBarry Smith     ierr = (*C->ops->matmultnumeric)(A,B,C);CHKERRQ(ierr);
1823fd4e9aacSBarry Smith     PetscFunctionReturn(0);
1824fd4e9aacSBarry Smith   }
1825fd4e9aacSBarry Smith 
1826fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&flg);CHKERRQ(ierr);
1827fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"First matrix must be dense");
1828c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1829c5df96a5SBarry Smith   ierr = PetscBLASIntCast(B->cmap->n,&n);CHKERRQ(ierr);
1830c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
18315ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
1832a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1833a9fe9ddaSSatish Balay }
1834a9fe9ddaSSatish Balay 
183575648e8dSHong Zhang PetscErrorCode MatTransposeMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
1836a9fe9ddaSSatish Balay {
1837a9fe9ddaSSatish Balay   PetscErrorCode ierr;
1838a9fe9ddaSSatish Balay 
1839a9fe9ddaSSatish Balay   PetscFunctionBegin;
1840a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
18413ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
184275648e8dSHong Zhang     ierr = MatTransposeMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
18433ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
1844a9fe9ddaSSatish Balay   }
18453ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
184675648e8dSHong Zhang   ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
18473ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
1848a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1849a9fe9ddaSSatish Balay }
1850a9fe9ddaSSatish Balay 
185175648e8dSHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
1852a9fe9ddaSSatish Balay {
1853ee16a9a1SHong Zhang   PetscErrorCode ierr;
1854d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
1855ee16a9a1SHong Zhang   Mat            Cmat;
1856a9fe9ddaSSatish Balay 
1857ee16a9a1SHong Zhang   PetscFunctionBegin;
1858e32f2f54SBarry 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);
1859ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
1860ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
1861ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
18620298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
18632205254eSKarl Rupp 
1864ee16a9a1SHong Zhang   Cmat->assembled = PETSC_TRUE;
18652205254eSKarl Rupp 
1866ee16a9a1SHong Zhang   *C = Cmat;
1867ee16a9a1SHong Zhang   PetscFunctionReturn(0);
1868ee16a9a1SHong Zhang }
1869a9fe9ddaSSatish Balay 
187075648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
1871a9fe9ddaSSatish Balay {
1872a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1873a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
1874a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
18750805154bSBarry Smith   PetscBLASInt   m,n,k;
1876a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
1877c5df96a5SBarry Smith   PetscErrorCode ierr;
1878a9fe9ddaSSatish Balay 
1879a9fe9ddaSSatish Balay   PetscFunctionBegin;
1880c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&m);CHKERRQ(ierr);
1881c5df96a5SBarry Smith   ierr = PetscBLASIntCast(B->cmap->n,&n);CHKERRQ(ierr);
1882c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
18832fbe02b9SBarry Smith   /*
18842fbe02b9SBarry Smith      Note the m and n arguments below are the number rows and columns of A', not A!
18852fbe02b9SBarry Smith   */
18865ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
1887a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1888a9fe9ddaSSatish Balay }
1889985db425SBarry Smith 
1890e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
1891985db425SBarry Smith {
1892985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1893985db425SBarry Smith   PetscErrorCode ierr;
1894d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
1895985db425SBarry Smith   PetscScalar    *x;
1896985db425SBarry Smith   MatScalar      *aa = a->v;
1897985db425SBarry Smith 
1898985db425SBarry Smith   PetscFunctionBegin;
1899e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1900985db425SBarry Smith 
1901985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
1902985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1903985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
1904e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1905985db425SBarry Smith   for (i=0; i<m; i++) {
1906985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
1907985db425SBarry Smith     for (j=1; j<n; j++) {
1908985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
1909985db425SBarry Smith     }
1910985db425SBarry Smith   }
1911985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1912985db425SBarry Smith   PetscFunctionReturn(0);
1913985db425SBarry Smith }
1914985db425SBarry Smith 
1915e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
1916985db425SBarry Smith {
1917985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1918985db425SBarry Smith   PetscErrorCode ierr;
1919d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
1920985db425SBarry Smith   PetscScalar    *x;
1921985db425SBarry Smith   PetscReal      atmp;
1922985db425SBarry Smith   MatScalar      *aa = a->v;
1923985db425SBarry Smith 
1924985db425SBarry Smith   PetscFunctionBegin;
1925e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1926985db425SBarry Smith 
1927985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
1928985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1929985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
1930e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1931985db425SBarry Smith   for (i=0; i<m; i++) {
19329189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
1933985db425SBarry Smith     for (j=1; j<n; j++) {
1934985db425SBarry Smith       atmp = PetscAbsScalar(aa[i+m*j]);
1935985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
1936985db425SBarry Smith     }
1937985db425SBarry Smith   }
1938985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1939985db425SBarry Smith   PetscFunctionReturn(0);
1940985db425SBarry Smith }
1941985db425SBarry Smith 
1942e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
1943985db425SBarry Smith {
1944985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1945985db425SBarry Smith   PetscErrorCode ierr;
1946d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
1947985db425SBarry Smith   PetscScalar    *x;
1948985db425SBarry Smith   MatScalar      *aa = a->v;
1949985db425SBarry Smith 
1950985db425SBarry Smith   PetscFunctionBegin;
1951e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1952985db425SBarry Smith 
1953985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
1954985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1955985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
1956e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1957985db425SBarry Smith   for (i=0; i<m; i++) {
1958985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
1959985db425SBarry Smith     for (j=1; j<n; j++) {
1960985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
1961985db425SBarry Smith     }
1962985db425SBarry Smith   }
1963985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1964985db425SBarry Smith   PetscFunctionReturn(0);
1965985db425SBarry Smith }
1966985db425SBarry Smith 
1967e0877f53SBarry Smith static PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
19688d0534beSBarry Smith {
19698d0534beSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
19708d0534beSBarry Smith   PetscErrorCode ierr;
19718d0534beSBarry Smith   PetscScalar    *x;
19728d0534beSBarry Smith 
19738d0534beSBarry Smith   PetscFunctionBegin;
1974e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
19758d0534beSBarry Smith 
19768d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1977d0f46423SBarry Smith   ierr = PetscMemcpy(x,a->v+col*a->lda,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
19788d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
19798d0534beSBarry Smith   PetscFunctionReturn(0);
19808d0534beSBarry Smith }
19818d0534beSBarry Smith 
19820716a85fSBarry Smith 
19830716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
19840716a85fSBarry Smith {
19850716a85fSBarry Smith   PetscErrorCode ierr;
19860716a85fSBarry Smith   PetscInt       i,j,m,n;
19870716a85fSBarry Smith   PetscScalar    *a;
19880716a85fSBarry Smith 
19890716a85fSBarry Smith   PetscFunctionBegin;
19900716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
19910716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
19928c778c55SBarry Smith   ierr = MatDenseGetArray(A,&a);CHKERRQ(ierr);
19930716a85fSBarry Smith   if (type == NORM_2) {
19940716a85fSBarry Smith     for (i=0; i<n; i++) {
19950716a85fSBarry Smith       for (j=0; j<m; j++) {
19960716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
19970716a85fSBarry Smith       }
19980716a85fSBarry Smith       a += m;
19990716a85fSBarry Smith     }
20000716a85fSBarry Smith   } else if (type == NORM_1) {
20010716a85fSBarry Smith     for (i=0; i<n; i++) {
20020716a85fSBarry Smith       for (j=0; j<m; j++) {
20030716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
20040716a85fSBarry Smith       }
20050716a85fSBarry Smith       a += m;
20060716a85fSBarry Smith     }
20070716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
20080716a85fSBarry Smith     for (i=0; i<n; i++) {
20090716a85fSBarry Smith       for (j=0; j<m; j++) {
20100716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
20110716a85fSBarry Smith       }
20120716a85fSBarry Smith       a += m;
20130716a85fSBarry Smith     }
2014ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
20158c778c55SBarry Smith   ierr = MatDenseRestoreArray(A,&a);CHKERRQ(ierr);
20160716a85fSBarry Smith   if (type == NORM_2) {
20178f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
20180716a85fSBarry Smith   }
20190716a85fSBarry Smith   PetscFunctionReturn(0);
20200716a85fSBarry Smith }
20210716a85fSBarry Smith 
202273a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
202373a71a0fSBarry Smith {
202473a71a0fSBarry Smith   PetscErrorCode ierr;
202573a71a0fSBarry Smith   PetscScalar    *a;
202673a71a0fSBarry Smith   PetscInt       m,n,i;
202773a71a0fSBarry Smith 
202873a71a0fSBarry Smith   PetscFunctionBegin;
202973a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
20308c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
203173a71a0fSBarry Smith   for (i=0; i<m*n; i++) {
203273a71a0fSBarry Smith     ierr = PetscRandomGetValue(rctx,a+i);CHKERRQ(ierr);
203373a71a0fSBarry Smith   }
20348c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
203573a71a0fSBarry Smith   PetscFunctionReturn(0);
203673a71a0fSBarry Smith }
203773a71a0fSBarry Smith 
20383b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
20393b49f96aSBarry Smith {
20403b49f96aSBarry Smith   PetscFunctionBegin;
20413b49f96aSBarry Smith   *missing = PETSC_FALSE;
20423b49f96aSBarry Smith   PetscFunctionReturn(0);
20433b49f96aSBarry Smith }
204473a71a0fSBarry Smith 
2045abc3b08eSStefano Zampini 
2046289bc588SBarry Smith /* -------------------------------------------------------------------*/
2047a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2048905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2049905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2050905e6a2fSBarry Smith                                         MatMult_SeqDense,
205197304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
20527c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
20537c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2054db4efbfdSBarry Smith                                         0,
2055db4efbfdSBarry Smith                                         0,
2056db4efbfdSBarry Smith                                         0,
2057db4efbfdSBarry Smith                                 /* 10*/ 0,
2058905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2059905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
206041f059aeSBarry Smith                                         MatSOR_SeqDense,
2061ec8511deSBarry Smith                                         MatTranspose_SeqDense,
206297304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2063905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2064905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2065905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2066905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2067c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2068c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2069905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2070905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2071d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2072db4efbfdSBarry Smith                                         0,
2073db4efbfdSBarry Smith                                         0,
2074db4efbfdSBarry Smith                                         0,
2075db4efbfdSBarry Smith                                         0,
20764994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2077273d9f13SBarry Smith                                         0,
2078905e6a2fSBarry Smith                                         0,
207973a71a0fSBarry Smith                                         0,
208073a71a0fSBarry Smith                                         0,
2081d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2082a5ae1ecdSBarry Smith                                         0,
2083a5ae1ecdSBarry Smith                                         0,
2084a5ae1ecdSBarry Smith                                         0,
2085a5ae1ecdSBarry Smith                                         0,
2086d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
20877dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2088a5ae1ecdSBarry Smith                                         0,
20894b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2090a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2091d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2092a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
20937d68702bSBarry Smith                                         MatShift_Basic,
2094a5ae1ecdSBarry Smith                                         0,
20953f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
209673a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2097a5ae1ecdSBarry Smith                                         0,
2098a5ae1ecdSBarry Smith                                         0,
2099a5ae1ecdSBarry Smith                                         0,
2100a5ae1ecdSBarry Smith                                         0,
2101d519adbfSMatthew Knepley                                 /* 54*/ 0,
2102a5ae1ecdSBarry Smith                                         0,
2103a5ae1ecdSBarry Smith                                         0,
2104a5ae1ecdSBarry Smith                                         0,
2105a5ae1ecdSBarry Smith                                         0,
2106d519adbfSMatthew Knepley                                 /* 59*/ 0,
2107e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2108e03a110bSBarry Smith                                         MatView_SeqDense,
2109357abbc8SBarry Smith                                         0,
211097304618SKris Buschelman                                         0,
2111d519adbfSMatthew Knepley                                 /* 64*/ 0,
211297304618SKris Buschelman                                         0,
211397304618SKris Buschelman                                         0,
211497304618SKris Buschelman                                         0,
211597304618SKris Buschelman                                         0,
2116d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
211797304618SKris Buschelman                                         0,
211897304618SKris Buschelman                                         0,
211997304618SKris Buschelman                                         0,
212097304618SKris Buschelman                                         0,
2121d519adbfSMatthew Knepley                                 /* 74*/ 0,
212297304618SKris Buschelman                                         0,
212397304618SKris Buschelman                                         0,
212497304618SKris Buschelman                                         0,
212597304618SKris Buschelman                                         0,
2126d519adbfSMatthew Knepley                                 /* 79*/ 0,
212797304618SKris Buschelman                                         0,
212897304618SKris Buschelman                                         0,
212997304618SKris Buschelman                                         0,
21305bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2131865e5f61SKris Buschelman                                         0,
21321cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2133865e5f61SKris Buschelman                                         0,
2134865e5f61SKris Buschelman                                         0,
2135865e5f61SKris Buschelman                                         0,
2136d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqDense_SeqDense,
2137a9fe9ddaSSatish Balay                                         MatMatMultSymbolic_SeqDense_SeqDense,
2138a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2139abc3b08eSStefano Zampini                                         MatPtAP_SeqDense_SeqDense,
2140abc3b08eSStefano Zampini                                         MatPtAPSymbolic_SeqDense_SeqDense,
2141abc3b08eSStefano Zampini                                 /* 94*/ MatPtAPNumeric_SeqDense_SeqDense,
21425df89d91SHong Zhang                                         0,
21435df89d91SHong Zhang                                         0,
21445df89d91SHong Zhang                                         0,
2145284134d9SBarry Smith                                         0,
2146d519adbfSMatthew Knepley                                 /* 99*/ 0,
2147284134d9SBarry Smith                                         0,
2148284134d9SBarry Smith                                         0,
2149ba337c44SJed Brown                                         MatConjugate_SeqDense,
2150f73d5cc4SBarry Smith                                         0,
2151ba337c44SJed Brown                                 /*104*/ 0,
2152ba337c44SJed Brown                                         MatRealPart_SeqDense,
2153ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2154985db425SBarry Smith                                         0,
2155985db425SBarry Smith                                         0,
215685e2c93fSHong Zhang                                 /*109*/ MatMatSolve_SeqDense,
2157985db425SBarry Smith                                         0,
21588d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2159aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
21603b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2161aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2162aabbc4fbSShri Abhyankar                                         0,
2163aabbc4fbSShri Abhyankar                                         0,
2164aabbc4fbSShri Abhyankar                                         0,
2165aabbc4fbSShri Abhyankar                                         0,
2166aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2167aabbc4fbSShri Abhyankar                                         0,
2168aabbc4fbSShri Abhyankar                                         0,
21690716a85fSBarry Smith                                         0,
21700716a85fSBarry Smith                                         0,
21710716a85fSBarry Smith                                 /*124*/ 0,
21725df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
21735df89d91SHong Zhang                                         0,
21745df89d91SHong Zhang                                         0,
21755df89d91SHong Zhang                                         0,
21765df89d91SHong Zhang                                 /*129*/ 0,
217775648e8dSHong Zhang                                         MatTransposeMatMult_SeqDense_SeqDense,
217875648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqDense_SeqDense,
217975648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
21803964eb88SJed Brown                                         0,
21813964eb88SJed Brown                                 /*134*/ 0,
21823964eb88SJed Brown                                         0,
21833964eb88SJed Brown                                         0,
21843964eb88SJed Brown                                         0,
21853964eb88SJed Brown                                         0,
21863964eb88SJed Brown                                 /*139*/ 0,
2187f9426fe0SMark Adams                                         0,
21883964eb88SJed Brown                                         0
2189985db425SBarry Smith };
219090ace30eSBarry Smith 
21914b828684SBarry Smith /*@C
2192fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2193d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2194d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2195289bc588SBarry Smith 
2196db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2197db81eaa0SLois Curfman McInnes 
219820563c6bSBarry Smith    Input Parameters:
2199db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
22000c775827SLois Curfman McInnes .  m - number of rows
220118f449edSLois Curfman McInnes .  n - number of columns
22020298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2203dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
220420563c6bSBarry Smith 
220520563c6bSBarry Smith    Output Parameter:
220644cd7ae7SLois Curfman McInnes .  A - the matrix
220720563c6bSBarry Smith 
2208b259b22eSLois Curfman McInnes    Notes:
220918f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
221018f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
22110298fd71SBarry Smith    set data=NULL.
221218f449edSLois Curfman McInnes 
2213027ccd11SLois Curfman McInnes    Level: intermediate
2214027ccd11SLois Curfman McInnes 
2215dbd7a890SLois Curfman McInnes .keywords: dense, matrix, LAPACK, BLAS
2216d65003e9SLois Curfman McInnes 
221769b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
221820563c6bSBarry Smith @*/
22197087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2220289bc588SBarry Smith {
2221dfbe8321SBarry Smith   PetscErrorCode ierr;
22223b2fbd54SBarry Smith 
22233a40ed3dSBarry Smith   PetscFunctionBegin;
2224f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2225f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2226273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2227273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2228273d9f13SBarry Smith   PetscFunctionReturn(0);
2229273d9f13SBarry Smith }
2230273d9f13SBarry Smith 
2231273d9f13SBarry Smith /*@C
2232273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2233273d9f13SBarry Smith 
2234273d9f13SBarry Smith    Collective on MPI_Comm
2235273d9f13SBarry Smith 
2236273d9f13SBarry Smith    Input Parameters:
22371c4f3114SJed Brown +  B - the matrix
22380298fd71SBarry Smith -  data - the array (or NULL)
2239273d9f13SBarry Smith 
2240273d9f13SBarry Smith    Notes:
2241273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2242273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2243284134d9SBarry Smith    need not call this routine.
2244273d9f13SBarry Smith 
2245273d9f13SBarry Smith    Level: intermediate
2246273d9f13SBarry Smith 
2247273d9f13SBarry Smith .keywords: dense, matrix, LAPACK, BLAS
2248273d9f13SBarry Smith 
224969b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA()
2250867c911aSBarry Smith 
2251273d9f13SBarry Smith @*/
22527087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2253273d9f13SBarry Smith {
22544ac538c5SBarry Smith   PetscErrorCode ierr;
2255a23d5eceSKris Buschelman 
2256a23d5eceSKris Buschelman   PetscFunctionBegin;
22574ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2258a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2259a23d5eceSKris Buschelman }
2260a23d5eceSKris Buschelman 
22617087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2262a23d5eceSKris Buschelman {
2263273d9f13SBarry Smith   Mat_SeqDense   *b;
2264dfbe8321SBarry Smith   PetscErrorCode ierr;
2265273d9f13SBarry Smith 
2266273d9f13SBarry Smith   PetscFunctionBegin;
2267273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2268a868139aSShri Abhyankar 
226934ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
227034ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
227134ef9618SShri Abhyankar 
2272273d9f13SBarry Smith   b       = (Mat_SeqDense*)B->data;
227386d161a7SShri Abhyankar   b->Mmax = B->rmap->n;
227486d161a7SShri Abhyankar   b->Nmax = B->cmap->n;
227586d161a7SShri Abhyankar   if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n;
227686d161a7SShri Abhyankar 
2277220afb94SBarry Smith   ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr);
22789e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
22799e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2280e92229d0SSatish Balay     ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr);
22813bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
22822205254eSKarl Rupp 
22839e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2284273d9f13SBarry Smith   } else { /* user-allocated storage */
22859e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2286273d9f13SBarry Smith     b->v          = data;
2287273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2288273d9f13SBarry Smith   }
22890450473dSBarry Smith   B->assembled = PETSC_TRUE;
2290273d9f13SBarry Smith   PetscFunctionReturn(0);
2291273d9f13SBarry Smith }
2292273d9f13SBarry Smith 
229365b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2294cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
22958baccfbdSHong Zhang {
2296d77f618aSHong Zhang   Mat            mat_elemental;
2297d77f618aSHong Zhang   PetscErrorCode ierr;
2298d77f618aSHong Zhang   PetscScalar    *array,*v_colwise;
2299d77f618aSHong Zhang   PetscInt       M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2300d77f618aSHong Zhang 
23018baccfbdSHong Zhang   PetscFunctionBegin;
2302d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
2303d77f618aSHong Zhang   ierr = MatDenseGetArray(A,&array);CHKERRQ(ierr);
2304d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2305d77f618aSHong Zhang   k = 0;
2306d77f618aSHong Zhang   for (j=0; j<N; j++) {
2307d77f618aSHong Zhang     cols[j] = j;
2308d77f618aSHong Zhang     for (i=0; i<M; i++) {
2309d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2310d77f618aSHong Zhang     }
2311d77f618aSHong Zhang   }
2312d77f618aSHong Zhang   for (i=0; i<M; i++) {
2313d77f618aSHong Zhang     rows[i] = i;
2314d77f618aSHong Zhang   }
2315d77f618aSHong Zhang   ierr = MatDenseRestoreArray(A,&array);CHKERRQ(ierr);
2316d77f618aSHong Zhang 
2317d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2318d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2319d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2320d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2321d77f618aSHong Zhang 
2322d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2323d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2324d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2325d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2326d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2327d77f618aSHong Zhang 
2328511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
232928be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2330d77f618aSHong Zhang   } else {
2331d77f618aSHong Zhang     *newmat = mat_elemental;
2332d77f618aSHong Zhang   }
23338baccfbdSHong Zhang   PetscFunctionReturn(0);
23348baccfbdSHong Zhang }
233565b80a83SHong Zhang #endif
23368baccfbdSHong Zhang 
23371b807ce4Svictorle /*@C
23381b807ce4Svictorle   MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array
23391b807ce4Svictorle 
23401b807ce4Svictorle   Input parameter:
23411b807ce4Svictorle + A - the matrix
23421b807ce4Svictorle - lda - the leading dimension
23431b807ce4Svictorle 
23441b807ce4Svictorle   Notes:
2345867c911aSBarry Smith   This routine is to be used in conjunction with MatSeqDenseSetPreallocation();
23461b807ce4Svictorle   it asserts that the preallocation has a leading dimension (the LDA parameter
23471b807ce4Svictorle   of Blas and Lapack fame) larger than M, the first dimension of the matrix.
23481b807ce4Svictorle 
23491b807ce4Svictorle   Level: intermediate
23501b807ce4Svictorle 
23511b807ce4Svictorle .keywords: dense, matrix, LAPACK, BLAS
23521b807ce4Svictorle 
2353284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize()
2354867c911aSBarry Smith 
23551b807ce4Svictorle @*/
23567087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetLDA(Mat B,PetscInt lda)
23571b807ce4Svictorle {
23581b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
235921a2c019SBarry Smith 
23601b807ce4Svictorle   PetscFunctionBegin;
2361e32f2f54SBarry 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);
23621b807ce4Svictorle   b->lda       = lda;
236321a2c019SBarry Smith   b->changelda = PETSC_FALSE;
236421a2c019SBarry Smith   b->Mmax      = PetscMax(b->Mmax,lda);
23651b807ce4Svictorle   PetscFunctionReturn(0);
23661b807ce4Svictorle }
23671b807ce4Svictorle 
23680bad9183SKris Buschelman /*MC
2369fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
23700bad9183SKris Buschelman 
23710bad9183SKris Buschelman    Options Database Keys:
23720bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
23730bad9183SKris Buschelman 
23740bad9183SKris Buschelman   Level: beginner
23750bad9183SKris Buschelman 
237689665df3SBarry Smith .seealso: MatCreateSeqDense()
237789665df3SBarry Smith 
23780bad9183SKris Buschelman M*/
23790bad9183SKris Buschelman 
23808cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqDense(Mat B)
2381273d9f13SBarry Smith {
2382273d9f13SBarry Smith   Mat_SeqDense   *b;
2383dfbe8321SBarry Smith   PetscErrorCode ierr;
23847c334f02SBarry Smith   PetscMPIInt    size;
2385273d9f13SBarry Smith 
2386273d9f13SBarry Smith   PetscFunctionBegin;
2387ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
2388e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
238955659b69SBarry Smith 
2390b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
2391549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
239244cd7ae7SLois Curfman McInnes   B->data = (void*)b;
239318f449edSLois Curfman McInnes 
239444cd7ae7SLois Curfman McInnes   b->pivots      = 0;
2395273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
2396273d9f13SBarry Smith   b->v           = 0;
239721a2c019SBarry Smith   b->changelda   = PETSC_FALSE;
23984e220ebcSLois Curfman McInnes 
2399bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2400*d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
2401*d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
2402bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2403bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
24048baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
24058baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
24068baccfbdSHong Zhang #endif
2407bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
2408bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaij_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2409bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2410bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2411abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaij_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
24123bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaij_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
24133bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
24143bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
241517667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
24163a40ed3dSBarry Smith   PetscFunctionReturn(0);
2417289bc588SBarry Smith }
2418