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