xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 8c1788164418143d00d14c33c989b0d7ba7e9a8a)
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 
11*8c178816SStefano Zampini static PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian)
12*8c178816SStefano Zampini {
13*8c178816SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
14*8c178816SStefano Zampini   PetscInt      j, k, n = A->rmap->n;
15*8c178816SStefano Zampini 
16*8c178816SStefano Zampini   PetscFunctionBegin;
17*8c178816SStefano Zampini   if (A->rmap->n != A->cmap->n) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot symmetrize a rectangular matrix");
18*8c178816SStefano Zampini   if (!hermitian) {
19*8c178816SStefano Zampini     for (k=0;k<n;k++) {
20*8c178816SStefano Zampini       for (j=k;j<n;j++) {
21*8c178816SStefano Zampini         mat->v[j*mat->lda + k] = mat->v[k*mat->lda + j];
22*8c178816SStefano Zampini       }
23*8c178816SStefano Zampini     }
24*8c178816SStefano Zampini   } else {
25*8c178816SStefano Zampini     for (k=0;k<n;k++) {
26*8c178816SStefano Zampini       for (j=k;j<n;j++) {
27*8c178816SStefano Zampini         mat->v[j*mat->lda + k] = PetscConj(mat->v[k*mat->lda + j]);
28*8c178816SStefano Zampini       }
29*8c178816SStefano Zampini     }
30*8c178816SStefano Zampini   }
31*8c178816SStefano Zampini   PetscFunctionReturn(0);
32*8c178816SStefano Zampini }
33*8c178816SStefano Zampini 
34*8c178816SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A)
35*8c178816SStefano Zampini {
36*8c178816SStefano Zampini #if defined(PETSC_MISSING_LAPACK_POTRF)
37*8c178816SStefano Zampini   PetscFunctionBegin;
38*8c178816SStefano Zampini   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF - Lapack routine is unavailable.");
39*8c178816SStefano Zampini #else
40*8c178816SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
41*8c178816SStefano Zampini   PetscErrorCode ierr;
42*8c178816SStefano Zampini   PetscBLASInt   info,n;
43*8c178816SStefano Zampini 
44*8c178816SStefano Zampini   PetscFunctionBegin;
45*8c178816SStefano Zampini   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
46*8c178816SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
47*8c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
48*8c178816SStefano Zampini     if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
49*8c178816SStefano Zampini     if (!mat->fwork) {
50*8c178816SStefano Zampini       mat->lfwork = n;
51*8c178816SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
52*8c178816SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
53*8c178816SStefano Zampini     }
54*8c178816SStefano Zampini     PetscStackCallBLAS("LAPACKgetri",LAPACKgetri_(&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
55*8c178816SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr); /* TODO CHECK FLOPS */
56*8c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
57*8c178816SStefano Zampini     if (A->spd) {
58*8c178816SStefano Zampini       PetscStackCallBLAS("LAPACKpotri",LAPACKpotri_("L",&n,mat->v,&mat->lda,&info));
59*8c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
60*8c178816SStefano Zampini #if defined (PETSC_USE_COMPLEX)
61*8c178816SStefano Zampini     } else if (A->hermitian) {
62*8c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
63*8c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
64*8c178816SStefano Zampini       PetscStackCallBLAS("LAPACKhetri",LAPACKhetri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
65*8c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
66*8c178816SStefano Zampini #endif
67*8c178816SStefano Zampini     } else { /* symmetric case */
68*8c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
69*8c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
70*8c178816SStefano Zampini       PetscStackCallBLAS("LAPACKsytri",LAPACKsytri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
71*8c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_FALSE);CHKERRQ(ierr);
72*8c178816SStefano Zampini     }
73*8c178816SStefano Zampini     if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad Inversion: zero pivot in row %D",(PetscInt)info-1);
74*8c178816SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr); /* TODO CHECK FLOPS */
75*8c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
76*8c178816SStefano Zampini #endif
77*8c178816SStefano Zampini 
78*8c178816SStefano Zampini   A->ops->solve             = NULL;
79*8c178816SStefano Zampini   A->ops->matsolve          = NULL;
80*8c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
81*8c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
82*8c178816SStefano Zampini   A->ops->solveadd          = NULL;
83*8c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
84*8c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
85*8c178816SStefano Zampini   ierr                      = PetscFree(A->solvertype);CHKERRQ(ierr);
86*8c178816SStefano Zampini   PetscFunctionReturn(0);
87*8c178816SStefano Zampini }
88*8c178816SStefano Zampini 
893f49a652SStefano Zampini PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
903f49a652SStefano Zampini {
913f49a652SStefano Zampini   PetscErrorCode    ierr;
923f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
933f49a652SStefano Zampini   PetscInt          m  = l->lda, n = A->cmap->n,r = A->rmap->n, i,j;
943f49a652SStefano Zampini   PetscScalar       *slot,*bb;
953f49a652SStefano Zampini   const PetscScalar *xx;
963f49a652SStefano Zampini 
973f49a652SStefano Zampini   PetscFunctionBegin;
983f49a652SStefano Zampini #if defined(PETSC_USE_DEBUG)
993f49a652SStefano Zampini   for (i=0; i<N; i++) {
1003f49a652SStefano Zampini     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1013f49a652SStefano 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);
1023f49a652SStefano 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);
1033f49a652SStefano Zampini   }
1043f49a652SStefano Zampini #endif
1053f49a652SStefano Zampini 
1063f49a652SStefano Zampini   /* fix right hand side if needed */
1073f49a652SStefano Zampini   if (x && b) {
1083f49a652SStefano Zampini     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1093f49a652SStefano Zampini     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
1103f49a652SStefano Zampini     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
1113f49a652SStefano Zampini     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1123f49a652SStefano Zampini     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
1133f49a652SStefano Zampini   }
1143f49a652SStefano Zampini 
1153f49a652SStefano Zampini   for (i=0; i<N; i++) {
1163f49a652SStefano Zampini     slot = l->v + rows[i]*m;
1173f49a652SStefano Zampini     ierr = PetscMemzero(slot,r*sizeof(PetscScalar));CHKERRQ(ierr);
1183f49a652SStefano Zampini   }
1193f49a652SStefano Zampini   for (i=0; i<N; i++) {
1203f49a652SStefano Zampini     slot = l->v + rows[i];
1213f49a652SStefano Zampini     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
1223f49a652SStefano Zampini   }
1233f49a652SStefano Zampini   if (diag != 0.0) {
1243f49a652SStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1253f49a652SStefano Zampini     for (i=0; i<N; i++) {
1263f49a652SStefano Zampini       slot  = l->v + (m+1)*rows[i];
1273f49a652SStefano Zampini       *slot = diag;
1283f49a652SStefano Zampini     }
1293f49a652SStefano Zampini   }
1303f49a652SStefano Zampini   PetscFunctionReturn(0);
1313f49a652SStefano Zampini }
1323f49a652SStefano Zampini 
133abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C)
134abc3b08eSStefano Zampini {
135abc3b08eSStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)(C->data);
136abc3b08eSStefano Zampini   PetscErrorCode ierr;
137abc3b08eSStefano Zampini 
138abc3b08eSStefano Zampini   PetscFunctionBegin;
139abc3b08eSStefano Zampini   ierr = MatMatMultNumeric_SeqDense_SeqDense(A,P,c->ptapwork);CHKERRQ(ierr);
140abc3b08eSStefano Zampini   ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(P,c->ptapwork,C);CHKERRQ(ierr);
141abc3b08eSStefano Zampini   PetscFunctionReturn(0);
142abc3b08eSStefano Zampini }
143abc3b08eSStefano Zampini 
144abc3b08eSStefano Zampini PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat *C)
145abc3b08eSStefano Zampini {
146abc3b08eSStefano Zampini   Mat_SeqDense   *c;
147abc3b08eSStefano Zampini   PetscErrorCode ierr;
148abc3b08eSStefano Zampini 
149abc3b08eSStefano Zampini   PetscFunctionBegin;
150abc3b08eSStefano Zampini   ierr = MatCreateSeqDense(PetscObjectComm((PetscObject)A),P->cmap->N,P->cmap->N,NULL,C);CHKERRQ(ierr);
151abc3b08eSStefano Zampini   c = (Mat_SeqDense*)((*C)->data);
152abc3b08eSStefano Zampini   ierr = MatCreateSeqDense(PetscObjectComm((PetscObject)A),A->rmap->N,P->cmap->N,NULL,&c->ptapwork);CHKERRQ(ierr);
153abc3b08eSStefano Zampini   PetscFunctionReturn(0);
154abc3b08eSStefano Zampini }
155abc3b08eSStefano Zampini 
156150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatPtAP_SeqDense_SeqDense(Mat A,Mat P,MatReuse reuse,PetscReal fill,Mat *C)
157abc3b08eSStefano Zampini {
158abc3b08eSStefano Zampini   PetscErrorCode ierr;
159abc3b08eSStefano Zampini 
160abc3b08eSStefano Zampini   PetscFunctionBegin;
161abc3b08eSStefano Zampini   if (reuse == MAT_INITIAL_MATRIX) {
162abc3b08eSStefano Zampini     ierr = MatPtAPSymbolic_SeqDense_SeqDense(A,P,fill,C);CHKERRQ(ierr);
163abc3b08eSStefano Zampini   }
164abc3b08eSStefano Zampini   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
165abc3b08eSStefano Zampini   ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
166abc3b08eSStefano Zampini   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
167abc3b08eSStefano Zampini   PetscFunctionReturn(0);
168abc3b08eSStefano Zampini }
169abc3b08eSStefano Zampini 
170cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
171b49cda9fSStefano Zampini {
172a13144ffSStefano Zampini   Mat            B = NULL;
173b49cda9fSStefano Zampini   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
174b49cda9fSStefano Zampini   Mat_SeqDense   *b;
175b49cda9fSStefano Zampini   PetscErrorCode ierr;
176b49cda9fSStefano Zampini   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i;
177b49cda9fSStefano Zampini   MatScalar      *av=a->a;
178a13144ffSStefano Zampini   PetscBool      isseqdense;
179b49cda9fSStefano Zampini 
180b49cda9fSStefano Zampini   PetscFunctionBegin;
181a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
182a13144ffSStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense);CHKERRQ(ierr);
183a13144ffSStefano Zampini     if (!isseqdense) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type);
184a13144ffSStefano Zampini   }
185a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
186b49cda9fSStefano Zampini     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
187b49cda9fSStefano Zampini     ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
188b49cda9fSStefano Zampini     ierr = MatSetType(B,MATSEQDENSE);CHKERRQ(ierr);
189b49cda9fSStefano Zampini     ierr = MatSeqDenseSetPreallocation(B,NULL);CHKERRQ(ierr);
190b49cda9fSStefano Zampini     b    = (Mat_SeqDense*)(B->data);
191a13144ffSStefano Zampini   } else {
192a13144ffSStefano Zampini     b    = (Mat_SeqDense*)((*newmat)->data);
193a13144ffSStefano Zampini     ierr = PetscMemzero(b->v,m*n*sizeof(PetscScalar));CHKERRQ(ierr);
194a13144ffSStefano Zampini   }
195b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
196b49cda9fSStefano Zampini     PetscInt j;
197b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
198b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
199b49cda9fSStefano Zampini       aj++;
200b49cda9fSStefano Zampini       av++;
201b49cda9fSStefano Zampini     }
202b49cda9fSStefano Zampini     ai++;
203b49cda9fSStefano Zampini   }
204b49cda9fSStefano Zampini 
205511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
206a13144ffSStefano Zampini     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
207a13144ffSStefano Zampini     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20828be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
209b49cda9fSStefano Zampini   } else {
210a13144ffSStefano Zampini     if (B) *newmat = B;
211a13144ffSStefano Zampini     ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
212a13144ffSStefano Zampini     ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
213b49cda9fSStefano Zampini   }
214b49cda9fSStefano Zampini   PetscFunctionReturn(0);
215b49cda9fSStefano Zampini }
216b49cda9fSStefano Zampini 
217cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
2186a63e612SBarry Smith {
2196a63e612SBarry Smith   Mat            B;
2206a63e612SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2216a63e612SBarry Smith   PetscErrorCode ierr;
2229399e1b8SMatthew G. Knepley   PetscInt       i, j;
2239399e1b8SMatthew G. Knepley   PetscInt       *rows, *nnz;
2249399e1b8SMatthew G. Knepley   MatScalar      *aa = a->v, *vals;
2256a63e612SBarry Smith 
2266a63e612SBarry Smith   PetscFunctionBegin;
227ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
2286a63e612SBarry Smith   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
2296a63e612SBarry Smith   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
2309399e1b8SMatthew G. Knepley   ierr = PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals);CHKERRQ(ierr);
2319399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2329399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) ++nnz[i];
2336a63e612SBarry Smith     aa += a->lda;
2346a63e612SBarry Smith   }
2359399e1b8SMatthew G. Knepley   ierr = MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz);CHKERRQ(ierr);
2369399e1b8SMatthew G. Knepley   aa = a->v;
2379399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2389399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2399399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) {rows[numRows] = i; vals[numRows++] = aa[i];}
2409399e1b8SMatthew G. Knepley     ierr = MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr);
2419399e1b8SMatthew G. Knepley     aa  += a->lda;
2429399e1b8SMatthew G. Knepley   }
2439399e1b8SMatthew G. Knepley   ierr = PetscFree3(rows,nnz,vals);CHKERRQ(ierr);
2446a63e612SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2456a63e612SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2466a63e612SBarry Smith 
247511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
24828be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
2496a63e612SBarry Smith   } else {
2506a63e612SBarry Smith     *newmat = B;
2516a63e612SBarry Smith   }
2526a63e612SBarry Smith   PetscFunctionReturn(0);
2536a63e612SBarry Smith }
2546a63e612SBarry Smith 
255e0877f53SBarry Smith static PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
2561987afe7SBarry Smith {
2571987afe7SBarry Smith   Mat_SeqDense   *x     = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
258f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
25913f74950SBarry Smith   PetscInt       j;
2600805154bSBarry Smith   PetscBLASInt   N,m,ldax,lday,one = 1;
261efee365bSSatish Balay   PetscErrorCode ierr;
2623a40ed3dSBarry Smith 
2633a40ed3dSBarry Smith   PetscFunctionBegin;
264c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n*X->cmap->n,&N);CHKERRQ(ierr);
265c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n,&m);CHKERRQ(ierr);
266c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->lda,&ldax);CHKERRQ(ierr);
267c5df96a5SBarry Smith   ierr = PetscBLASIntCast(y->lda,&lday);CHKERRQ(ierr);
268a5ce6ee0Svictorle   if (ldax>m || lday>m) {
269d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
2708b83055fSJed Brown       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&oalpha,x->v+j*ldax,&one,y->v+j*lday,&one));
271a5ce6ee0Svictorle     }
272a5ce6ee0Svictorle   } else {
2738b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&oalpha,x->v,&one,y->v,&one));
274a5ce6ee0Svictorle   }
275a3fa217bSJose E. Roman   ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr);
2760450473dSBarry Smith   ierr = PetscLogFlops(PetscMax(2*N-1,0));CHKERRQ(ierr);
2773a40ed3dSBarry Smith   PetscFunctionReturn(0);
2781987afe7SBarry Smith }
2791987afe7SBarry Smith 
280e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
281289bc588SBarry Smith {
282d0f46423SBarry Smith   PetscInt N = A->rmap->n*A->cmap->n;
2833a40ed3dSBarry Smith 
2843a40ed3dSBarry Smith   PetscFunctionBegin;
2854e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
2864e220ebcSLois Curfman McInnes   info->nz_allocated      = (double)N;
2876de62eeeSBarry Smith   info->nz_used           = (double)N;
2886de62eeeSBarry Smith   info->nz_unneeded       = (double)0;
2894e220ebcSLois Curfman McInnes   info->assemblies        = (double)A->num_ass;
2904e220ebcSLois Curfman McInnes   info->mallocs           = 0;
2917adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
2924e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
2934e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
2944e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
2953a40ed3dSBarry Smith   PetscFunctionReturn(0);
296289bc588SBarry Smith }
297289bc588SBarry Smith 
298e0877f53SBarry Smith static PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
29980cd9d93SLois Curfman McInnes {
300273d9f13SBarry Smith   Mat_SeqDense   *a     = (Mat_SeqDense*)A->data;
301f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
302efee365bSSatish Balay   PetscErrorCode ierr;
303c5df96a5SBarry Smith   PetscBLASInt   one = 1,j,nz,lda;
30480cd9d93SLois Curfman McInnes 
3053a40ed3dSBarry Smith   PetscFunctionBegin;
306c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->lda,&lda);CHKERRQ(ierr);
307d0f46423SBarry Smith   if (lda>A->rmap->n) {
308c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n,&nz);CHKERRQ(ierr);
309d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
3108b83055fSJed Brown       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&oalpha,a->v+j*lda,&one));
311a5ce6ee0Svictorle     }
312a5ce6ee0Svictorle   } else {
313c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz);CHKERRQ(ierr);
3148b83055fSJed Brown     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&oalpha,a->v,&one));
315a5ce6ee0Svictorle   }
316efee365bSSatish Balay   ierr = PetscLogFlops(nz);CHKERRQ(ierr);
3173a40ed3dSBarry Smith   PetscFunctionReturn(0);
31880cd9d93SLois Curfman McInnes }
31980cd9d93SLois Curfman McInnes 
320e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3211cbb95d3SBarry Smith {
3221cbb95d3SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
323d0f46423SBarry Smith   PetscInt     i,j,m = A->rmap->n,N;
3241cbb95d3SBarry Smith   PetscScalar  *v = a->v;
3251cbb95d3SBarry Smith 
3261cbb95d3SBarry Smith   PetscFunctionBegin;
3271cbb95d3SBarry Smith   *fl = PETSC_FALSE;
328d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3291cbb95d3SBarry Smith   N = a->lda;
3301cbb95d3SBarry Smith 
3311cbb95d3SBarry Smith   for (i=0; i<m; i++) {
3321cbb95d3SBarry Smith     for (j=i+1; j<m; j++) {
3331cbb95d3SBarry Smith       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) PetscFunctionReturn(0);
3341cbb95d3SBarry Smith     }
3351cbb95d3SBarry Smith   }
3361cbb95d3SBarry Smith   *fl = PETSC_TRUE;
3371cbb95d3SBarry Smith   PetscFunctionReturn(0);
3381cbb95d3SBarry Smith }
3391cbb95d3SBarry Smith 
340e0877f53SBarry Smith static PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
341b24902e0SBarry Smith {
342b24902e0SBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data,*l;
343b24902e0SBarry Smith   PetscErrorCode ierr;
344b24902e0SBarry Smith   PetscInt       lda = (PetscInt)mat->lda,j,m;
345b24902e0SBarry Smith 
346b24902e0SBarry Smith   PetscFunctionBegin;
347aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr);
348aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr);
3490298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr);
350b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
351b24902e0SBarry Smith     l = (Mat_SeqDense*)newi->data;
352d0f46423SBarry Smith     if (lda>A->rmap->n) {
353d0f46423SBarry Smith       m = A->rmap->n;
354d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
355b24902e0SBarry Smith         ierr = PetscMemcpy(l->v+j*m,mat->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr);
356b24902e0SBarry Smith       }
357b24902e0SBarry Smith     } else {
358d0f46423SBarry Smith       ierr = PetscMemcpy(l->v,mat->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
359b24902e0SBarry Smith     }
360b24902e0SBarry Smith   }
361b24902e0SBarry Smith   newi->assembled = PETSC_TRUE;
362b24902e0SBarry Smith   PetscFunctionReturn(0);
363b24902e0SBarry Smith }
364b24902e0SBarry Smith 
365e0877f53SBarry Smith static PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
36602cad45dSBarry Smith {
3676849ba73SBarry Smith   PetscErrorCode ierr;
36802cad45dSBarry Smith 
3693a40ed3dSBarry Smith   PetscFunctionBegin;
370ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr);
371d0f46423SBarry Smith   ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
3725c9eb25fSBarry Smith   ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
373719d5645SBarry Smith   ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr);
374b24902e0SBarry Smith   PetscFunctionReturn(0);
375b24902e0SBarry Smith }
376b24902e0SBarry Smith 
3776ee01492SSatish Balay 
378e0877f53SBarry Smith static PetscErrorCode MatLUFactor_SeqDense(Mat,IS,IS,const MatFactorInfo*);
379719d5645SBarry Smith 
380e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
381289bc588SBarry Smith {
3824482741eSBarry Smith   MatFactorInfo  info;
383a093e273SMatthew Knepley   PetscErrorCode ierr;
3843a40ed3dSBarry Smith 
3853a40ed3dSBarry Smith   PetscFunctionBegin;
386c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
387719d5645SBarry Smith   ierr = MatLUFactor_SeqDense(fact,0,0,&info);CHKERRQ(ierr);
3883a40ed3dSBarry Smith   PetscFunctionReturn(0);
389289bc588SBarry Smith }
3906ee01492SSatish Balay 
391e0877f53SBarry Smith static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy)
392289bc588SBarry Smith {
393c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
3946849ba73SBarry Smith   PetscErrorCode    ierr;
395f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
396f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
397c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
39867e560aaSBarry Smith 
3993a40ed3dSBarry Smith   PetscFunctionBegin;
400c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
401f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4021ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
403d0f46423SBarry Smith   ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
404d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_LU) {
405ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
406e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
407ae7cfcebSSatish Balay #else
4088b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
409e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
410ae7cfcebSSatish Balay #endif
411d5f3da31SBarry Smith   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
412ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
413e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
414ae7cfcebSSatish Balay #else
415a49dc2a2SStefano Zampini     if (A->spd) {
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");
418a49dc2a2SStefano Zampini #if defined (PETSC_USE_COMPLEX)
419a49dc2a2SStefano Zampini     } else if (A->hermitian) {
420a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
421a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
422a49dc2a2SStefano Zampini #endif
423a49dc2a2SStefano Zampini     } else { /* symmetric case */
424a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
425a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
426a49dc2a2SStefano Zampini     }
427ae7cfcebSSatish Balay #endif
4282205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
429f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4301ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
431dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
4323a40ed3dSBarry Smith   PetscFunctionReturn(0);
433289bc588SBarry Smith }
4346ee01492SSatish Balay 
435e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X)
43685e2c93fSHong Zhang {
43785e2c93fSHong Zhang   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
43885e2c93fSHong Zhang   PetscErrorCode ierr;
43985e2c93fSHong Zhang   PetscScalar    *b,*x;
440efb80c78SLisandro Dalcin   PetscInt       n;
441783b601eSJed Brown   PetscBLASInt   nrhs,info,m;
442bda8bf91SBarry Smith   PetscBool      flg;
44385e2c93fSHong Zhang 
44485e2c93fSHong Zhang   PetscFunctionBegin;
445c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
4460298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
447ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
4480298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
449ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
450bda8bf91SBarry Smith 
4510298fd71SBarry Smith   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
452c5df96a5SBarry Smith   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
4538c778c55SBarry Smith   ierr = MatDenseGetArray(B,&b);CHKERRQ(ierr);
4548c778c55SBarry Smith   ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr);
45585e2c93fSHong Zhang 
456f272c775SHong Zhang   ierr = PetscMemcpy(x,b,m*nrhs*sizeof(PetscScalar));CHKERRQ(ierr);
45785e2c93fSHong Zhang 
45885e2c93fSHong Zhang   if (A->factortype == MAT_FACTOR_LU) {
45985e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_GETRS)
46085e2c93fSHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
46185e2c93fSHong Zhang #else
4628b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
46385e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
46485e2c93fSHong Zhang #endif
46585e2c93fSHong Zhang   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
46685e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_POTRS)
46785e2c93fSHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
46885e2c93fSHong Zhang #else
469a49dc2a2SStefano Zampini     if (A->spd) {
4708b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
47185e2c93fSHong Zhang       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
472a49dc2a2SStefano Zampini #if defined (PETSC_USE_COMPLEX)
473a49dc2a2SStefano Zampini     } else if (A->hermitian) {
474a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
475a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
476a49dc2a2SStefano Zampini #endif
477a49dc2a2SStefano Zampini     } else { /* symmetric case */
478a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
479a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
480a49dc2a2SStefano Zampini     }
48185e2c93fSHong Zhang #endif
4822205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
48385e2c93fSHong Zhang 
4848c778c55SBarry Smith   ierr = MatDenseRestoreArray(B,&b);CHKERRQ(ierr);
4858c778c55SBarry Smith   ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr);
48685e2c93fSHong Zhang   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
48785e2c93fSHong Zhang   PetscFunctionReturn(0);
48885e2c93fSHong Zhang }
48985e2c93fSHong Zhang 
490e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
491da3a660dSBarry Smith {
492c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
493dfbe8321SBarry Smith   PetscErrorCode    ierr;
494f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
495f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
496c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
49767e560aaSBarry Smith 
4983a40ed3dSBarry Smith   PetscFunctionBegin;
499c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
500f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5011ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
502d0f46423SBarry Smith   ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
5038208b9aeSStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
504ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
505e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
506ae7cfcebSSatish Balay #else
5078b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
508e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve");
509ae7cfcebSSatish Balay #endif
5108208b9aeSStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
511ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
512e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
513ae7cfcebSSatish Balay #else
514a49dc2a2SStefano Zampini     if (A->spd) {
5158b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
516a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
517a49dc2a2SStefano Zampini #if defined (PETSC_USE_COMPLEX)
518a49dc2a2SStefano Zampini     } else if (A->hermitian) {
519a49dc2a2SStefano Zampini       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatSolveTranspose with Cholesky/Hermitian not available");
520ae7cfcebSSatish Balay #endif
521a49dc2a2SStefano Zampini     } else { /* symmetric case */
522a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
523a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
524da3a660dSBarry Smith     }
525a49dc2a2SStefano Zampini #endif
526a49dc2a2SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
527f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5281ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
529dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
5303a40ed3dSBarry Smith   PetscFunctionReturn(0);
531da3a660dSBarry Smith }
5326ee01492SSatish Balay 
533e0877f53SBarry Smith static PetscErrorCode MatSolveAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
534da3a660dSBarry Smith {
535dfbe8321SBarry Smith   PetscErrorCode    ierr;
536f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
537f1ceaac6SMatthew G. Knepley   PetscScalar       *y,sone = 1.0;
538da3a660dSBarry Smith   Vec               tmp = 0;
53967e560aaSBarry Smith 
5403a40ed3dSBarry Smith   PetscFunctionBegin;
541f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5421ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
543d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
544da3a660dSBarry Smith   if (yy == zz) {
54578b31e54SBarry Smith     ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr);
5463bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)tmp);CHKERRQ(ierr);
54778b31e54SBarry Smith     ierr = VecCopy(yy,tmp);CHKERRQ(ierr);
548da3a660dSBarry Smith   }
5498208b9aeSStefano Zampini   ierr = MatSolve_SeqDense(A,xx,yy);CHKERRQ(ierr);
5506bf464f9SBarry Smith   if (tmp) {
5516bf464f9SBarry Smith     ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr);
5526bf464f9SBarry Smith     ierr = VecDestroy(&tmp);CHKERRQ(ierr);
5536bf464f9SBarry Smith   } else {
5546bf464f9SBarry Smith     ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr);
5556bf464f9SBarry Smith   }
556f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5571ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
5588208b9aeSStefano Zampini   ierr = PetscLogFlops(A->cmap->n);CHKERRQ(ierr);
5593a40ed3dSBarry Smith   PetscFunctionReturn(0);
560da3a660dSBarry Smith }
56167e560aaSBarry Smith 
562e0877f53SBarry Smith static PetscErrorCode MatSolveTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
563da3a660dSBarry Smith {
5646849ba73SBarry Smith   PetscErrorCode    ierr;
565f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
566f1ceaac6SMatthew G. Knepley   PetscScalar       *y,sone = 1.0;
56789ae1891SBarry Smith   Vec               tmp = NULL;
56867e560aaSBarry Smith 
5693a40ed3dSBarry Smith   PetscFunctionBegin;
570d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
571f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5721ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
573da3a660dSBarry Smith   if (yy == zz) {
57478b31e54SBarry Smith     ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr);
5753bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)tmp);CHKERRQ(ierr);
57678b31e54SBarry Smith     ierr = VecCopy(yy,tmp);CHKERRQ(ierr);
577da3a660dSBarry Smith   }
5788208b9aeSStefano Zampini   ierr = MatSolveTranspose_SeqDense(A,xx,yy);CHKERRQ(ierr);
57990f02eecSBarry Smith   if (tmp) {
5802dcb1b2aSMatthew Knepley     ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr);
5816bf464f9SBarry Smith     ierr = VecDestroy(&tmp);CHKERRQ(ierr);
5823a40ed3dSBarry Smith   } else {
5832dcb1b2aSMatthew Knepley     ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr);
58490f02eecSBarry Smith   }
585f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5861ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
5878208b9aeSStefano Zampini   ierr = PetscLogFlops(A->cmap->n);CHKERRQ(ierr);
5883a40ed3dSBarry Smith   PetscFunctionReturn(0);
589da3a660dSBarry Smith }
590db4efbfdSBarry Smith 
591db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
592db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
593db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
594e0877f53SBarry Smith static PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
595db4efbfdSBarry Smith {
596db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_GETRF)
597db4efbfdSBarry Smith   PetscFunctionBegin;
598e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRF - Lapack routine is unavailable.");
599db4efbfdSBarry Smith #else
600db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
601db4efbfdSBarry Smith   PetscErrorCode ierr;
602db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
603db4efbfdSBarry Smith 
604db4efbfdSBarry Smith   PetscFunctionBegin;
605c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
606c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
607db4efbfdSBarry Smith   if (!mat->pivots) {
6088208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
6093bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
610db4efbfdSBarry Smith   }
611db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
6128e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6138b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
6148e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
6158e57ea43SSatish Balay 
616e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
617e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
6188208b9aeSStefano Zampini 
619db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6208208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
621db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
622db4efbfdSBarry Smith   A->ops->solveadd          = MatSolveAdd_SeqDense;
623db4efbfdSBarry Smith   A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
624d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
625db4efbfdSBarry Smith 
626f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
627f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
628f6224b95SHong Zhang 
629dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
630db4efbfdSBarry Smith #endif
631db4efbfdSBarry Smith   PetscFunctionReturn(0);
632db4efbfdSBarry Smith }
633db4efbfdSBarry Smith 
634a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
635e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
636db4efbfdSBarry Smith {
637db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_POTRF)
638db4efbfdSBarry Smith   PetscFunctionBegin;
639e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF - Lapack routine is unavailable.");
640db4efbfdSBarry Smith #else
641db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
642db4efbfdSBarry Smith   PetscErrorCode ierr;
643c5df96a5SBarry Smith   PetscBLASInt   info,n;
644db4efbfdSBarry Smith 
645db4efbfdSBarry Smith   PetscFunctionBegin;
646c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
647db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
648a49dc2a2SStefano Zampini   if (A->spd) {
6498b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
650a49dc2a2SStefano Zampini #if defined (PETSC_USE_COMPLEX)
651a49dc2a2SStefano Zampini   } else if (A->hermitian) {
652a49dc2a2SStefano Zampini     if (!mat->pivots) {
653a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
654a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
655a49dc2a2SStefano Zampini     }
656a49dc2a2SStefano Zampini     if (!mat->fwork) {
657a49dc2a2SStefano Zampini       PetscScalar dummy;
658a49dc2a2SStefano Zampini 
659a49dc2a2SStefano Zampini       mat->lfwork = -1;
660a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
661a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
662a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
663a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
664a49dc2a2SStefano Zampini     }
665a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
666a49dc2a2SStefano Zampini #endif
667a49dc2a2SStefano Zampini   } else { /* symmetric case */
668a49dc2a2SStefano Zampini     if (!mat->pivots) {
669a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
670a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
671a49dc2a2SStefano Zampini     }
672a49dc2a2SStefano Zampini     if (!mat->fwork) {
673a49dc2a2SStefano Zampini       PetscScalar dummy;
674a49dc2a2SStefano Zampini 
675a49dc2a2SStefano Zampini       mat->lfwork = -1;
676a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
677a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
678a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
679a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
680a49dc2a2SStefano Zampini     }
681a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
682a49dc2a2SStefano Zampini   }
683e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
6848208b9aeSStefano Zampini 
685db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6868208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
687db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
688db4efbfdSBarry Smith   A->ops->solveadd          = MatSolveAdd_SeqDense;
689db4efbfdSBarry Smith   A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
690d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
6912205254eSKarl Rupp 
692f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
693f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
694f6224b95SHong Zhang 
695eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
696db4efbfdSBarry Smith #endif
697db4efbfdSBarry Smith   PetscFunctionReturn(0);
698db4efbfdSBarry Smith }
699db4efbfdSBarry Smith 
700db4efbfdSBarry Smith 
7010481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
702db4efbfdSBarry Smith {
703db4efbfdSBarry Smith   PetscErrorCode ierr;
704db4efbfdSBarry Smith   MatFactorInfo  info;
705db4efbfdSBarry Smith 
706db4efbfdSBarry Smith   PetscFunctionBegin;
707db4efbfdSBarry Smith   info.fill = 1.0;
7082205254eSKarl Rupp 
709c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
710719d5645SBarry Smith   ierr = MatCholeskyFactor_SeqDense(fact,0,&info);CHKERRQ(ierr);
711db4efbfdSBarry Smith   PetscFunctionReturn(0);
712db4efbfdSBarry Smith }
713db4efbfdSBarry Smith 
714e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
715db4efbfdSBarry Smith {
716db4efbfdSBarry Smith   PetscFunctionBegin;
717c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
7181bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
719719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
720db4efbfdSBarry Smith   PetscFunctionReturn(0);
721db4efbfdSBarry Smith }
722db4efbfdSBarry Smith 
723e0877f53SBarry Smith static PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
724db4efbfdSBarry Smith {
725db4efbfdSBarry Smith   PetscFunctionBegin;
726b66fe19dSMatthew G Knepley   fact->preallocated         = PETSC_TRUE;
727c3ef05f6SHong Zhang   fact->assembled            = PETSC_TRUE;
728719d5645SBarry Smith   fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense;
729db4efbfdSBarry Smith   PetscFunctionReturn(0);
730db4efbfdSBarry Smith }
731db4efbfdSBarry Smith 
732cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
733db4efbfdSBarry Smith {
734db4efbfdSBarry Smith   PetscErrorCode ierr;
735db4efbfdSBarry Smith 
736db4efbfdSBarry Smith   PetscFunctionBegin;
737ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
738db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
739db4efbfdSBarry Smith   ierr = MatSetType(*fact,((PetscObject)A)->type_name);CHKERRQ(ierr);
740db4efbfdSBarry Smith   if (ftype == MAT_FACTOR_LU) {
741db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
742db4efbfdSBarry Smith   } else {
743db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
744db4efbfdSBarry Smith   }
745d5f3da31SBarry Smith   (*fact)->factortype = ftype;
74600c67f3bSHong Zhang 
74700c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
74800c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
749db4efbfdSBarry Smith   PetscFunctionReturn(0);
750db4efbfdSBarry Smith }
751db4efbfdSBarry Smith 
752289bc588SBarry Smith /* ------------------------------------------------------------------*/
753e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
754289bc588SBarry Smith {
755c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
756d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
757d9ca1df4SBarry Smith   const PetscScalar *b;
758dfbe8321SBarry Smith   PetscErrorCode    ierr;
759d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
760c5df96a5SBarry Smith   PetscBLASInt      o = 1,bm;
761289bc588SBarry Smith 
7623a40ed3dSBarry Smith   PetscFunctionBegin;
763422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
764c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
765289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
76671044d3cSBarry Smith     /* this is a hack fix, should have another version without the second BLASdot */
7672dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
768289bc588SBarry Smith   }
7691ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
770d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
771b965ef7fSBarry Smith   its  = its*lits;
772e32f2f54SBarry 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);
773289bc588SBarry Smith   while (its--) {
774fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
775289bc588SBarry Smith       for (i=0; i<m; i++) {
7768b83055fSJed Brown         PetscStackCallBLAS("BLASdot",xt   = b[i] - BLASdot_(&bm,v+i,&bm,x,&o));
77755a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
778289bc588SBarry Smith       }
779289bc588SBarry Smith     }
780fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
781289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
7828b83055fSJed Brown         PetscStackCallBLAS("BLASdot",xt   = b[i] - BLASdot_(&bm,v+i,&bm,x,&o));
78355a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
784289bc588SBarry Smith       }
785289bc588SBarry Smith     }
786289bc588SBarry Smith   }
787d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
7881ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
7893a40ed3dSBarry Smith   PetscFunctionReturn(0);
790289bc588SBarry Smith }
791289bc588SBarry Smith 
792289bc588SBarry Smith /* -----------------------------------------------------------------*/
793cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
794289bc588SBarry Smith {
795c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
796d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
797d9ca1df4SBarry Smith   PetscScalar       *y;
798dfbe8321SBarry Smith   PetscErrorCode    ierr;
7990805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
800ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
8013a40ed3dSBarry Smith 
8023a40ed3dSBarry Smith   PetscFunctionBegin;
803c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
804c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
805d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
806d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8071ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8088b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
809d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8101ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
811dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
8123a40ed3dSBarry Smith   PetscFunctionReturn(0);
813289bc588SBarry Smith }
814800995b7SMatthew Knepley 
815cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
816289bc588SBarry Smith {
817c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
818d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
819dfbe8321SBarry Smith   PetscErrorCode    ierr;
8200805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
821d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
8223a40ed3dSBarry Smith 
8233a40ed3dSBarry Smith   PetscFunctionBegin;
824c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
825c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
826d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
827d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8281ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8298b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
830d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8311ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
832dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
8333a40ed3dSBarry Smith   PetscFunctionReturn(0);
834289bc588SBarry Smith }
8356ee01492SSatish Balay 
836cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
837289bc588SBarry Smith {
838c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
839d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
840d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
841dfbe8321SBarry Smith   PetscErrorCode    ierr;
8420805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
8433a40ed3dSBarry Smith 
8443a40ed3dSBarry Smith   PetscFunctionBegin;
845c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
846c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
847d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
848600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
849d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8501ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8518b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
852d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8531ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
854dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8553a40ed3dSBarry Smith   PetscFunctionReturn(0);
856289bc588SBarry Smith }
8576ee01492SSatish Balay 
858e0877f53SBarry Smith static PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
859289bc588SBarry Smith {
860c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
861d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
862d9ca1df4SBarry Smith   PetscScalar       *y;
863dfbe8321SBarry Smith   PetscErrorCode    ierr;
8640805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
86587828ca2SBarry Smith   PetscScalar       _DOne=1.0;
8663a40ed3dSBarry Smith 
8673a40ed3dSBarry Smith   PetscFunctionBegin;
868c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
869c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
870d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
871600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
872d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8731ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8748b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
875d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8761ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
877dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8783a40ed3dSBarry Smith   PetscFunctionReturn(0);
879289bc588SBarry Smith }
880289bc588SBarry Smith 
881289bc588SBarry Smith /* -----------------------------------------------------------------*/
882e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
883289bc588SBarry Smith {
884c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
88587828ca2SBarry Smith   PetscScalar    *v;
8866849ba73SBarry Smith   PetscErrorCode ierr;
88713f74950SBarry Smith   PetscInt       i;
88867e560aaSBarry Smith 
8893a40ed3dSBarry Smith   PetscFunctionBegin;
890d0f46423SBarry Smith   *ncols = A->cmap->n;
891289bc588SBarry Smith   if (cols) {
892854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
893d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
894289bc588SBarry Smith   }
895289bc588SBarry Smith   if (vals) {
896854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
897289bc588SBarry Smith     v    = mat->v + row;
898d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
899289bc588SBarry Smith   }
9003a40ed3dSBarry Smith   PetscFunctionReturn(0);
901289bc588SBarry Smith }
9026ee01492SSatish Balay 
903e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
904289bc588SBarry Smith {
905dfbe8321SBarry Smith   PetscErrorCode ierr;
9066e111a19SKarl Rupp 
907606d414cSSatish Balay   PetscFunctionBegin;
908606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
909606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
9103a40ed3dSBarry Smith   PetscFunctionReturn(0);
911289bc588SBarry Smith }
912289bc588SBarry Smith /* ----------------------------------------------------------------*/
913e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
914289bc588SBarry Smith {
915c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
91613f74950SBarry Smith   PetscInt     i,j,idx=0;
917d6dfbf8fSBarry Smith 
9183a40ed3dSBarry Smith   PetscFunctionBegin;
919289bc588SBarry Smith   if (!mat->roworiented) {
920dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
921289bc588SBarry Smith       for (j=0; j<n; j++) {
922cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
9232515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
924e32f2f54SBarry 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);
92558804f6dSBarry Smith #endif
926289bc588SBarry Smith         for (i=0; i<m; i++) {
927cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
9282515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
929e32f2f54SBarry 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);
93058804f6dSBarry Smith #endif
931cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
932289bc588SBarry Smith         }
933289bc588SBarry Smith       }
9343a40ed3dSBarry Smith     } else {
935289bc588SBarry Smith       for (j=0; j<n; j++) {
936cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
9372515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
938e32f2f54SBarry 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);
93958804f6dSBarry Smith #endif
940289bc588SBarry Smith         for (i=0; i<m; i++) {
941cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
9422515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
943e32f2f54SBarry 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);
94458804f6dSBarry Smith #endif
945cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
946289bc588SBarry Smith         }
947289bc588SBarry Smith       }
948289bc588SBarry Smith     }
9493a40ed3dSBarry Smith   } else {
950dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
951e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
952cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
9532515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
954e32f2f54SBarry 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);
95558804f6dSBarry Smith #endif
956e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
957cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
9582515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
959e32f2f54SBarry 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);
96058804f6dSBarry Smith #endif
961cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
962e8d4e0b9SBarry Smith         }
963e8d4e0b9SBarry Smith       }
9643a40ed3dSBarry Smith     } else {
965289bc588SBarry Smith       for (i=0; i<m; i++) {
966cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
9672515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
968e32f2f54SBarry 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);
96958804f6dSBarry Smith #endif
970289bc588SBarry Smith         for (j=0; j<n; j++) {
971cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
9722515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
973e32f2f54SBarry 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);
97458804f6dSBarry Smith #endif
975cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
976289bc588SBarry Smith         }
977289bc588SBarry Smith       }
978289bc588SBarry Smith     }
979e8d4e0b9SBarry Smith   }
9803a40ed3dSBarry Smith   PetscFunctionReturn(0);
981289bc588SBarry Smith }
982e8d4e0b9SBarry Smith 
983e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
984ae80bb75SLois Curfman McInnes {
985ae80bb75SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
98613f74950SBarry Smith   PetscInt     i,j;
987ae80bb75SLois Curfman McInnes 
9883a40ed3dSBarry Smith   PetscFunctionBegin;
989ae80bb75SLois Curfman McInnes   /* row-oriented output */
990ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
99197e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
992e32f2f54SBarry 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);
993ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
9946f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
995e32f2f54SBarry 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);
99697e567efSBarry Smith       *v++ = mat->v[indexn[j]*mat->lda + indexm[i]];
997ae80bb75SLois Curfman McInnes     }
998ae80bb75SLois Curfman McInnes   }
9993a40ed3dSBarry Smith   PetscFunctionReturn(0);
1000ae80bb75SLois Curfman McInnes }
1001ae80bb75SLois Curfman McInnes 
1002289bc588SBarry Smith /* -----------------------------------------------------------------*/
1003289bc588SBarry Smith 
1004e0877f53SBarry Smith static PetscErrorCode MatLoad_SeqDense(Mat newmat,PetscViewer viewer)
1005aabbc4fbSShri Abhyankar {
1006aabbc4fbSShri Abhyankar   Mat_SeqDense   *a;
1007aabbc4fbSShri Abhyankar   PetscErrorCode ierr;
1008aabbc4fbSShri Abhyankar   PetscInt       *scols,i,j,nz,header[4];
1009aabbc4fbSShri Abhyankar   int            fd;
1010aabbc4fbSShri Abhyankar   PetscMPIInt    size;
1011aabbc4fbSShri Abhyankar   PetscInt       *rowlengths = 0,M,N,*cols,grows,gcols;
1012aabbc4fbSShri Abhyankar   PetscScalar    *vals,*svals,*v,*w;
1013ce94432eSBarry Smith   MPI_Comm       comm;
1014aabbc4fbSShri Abhyankar 
1015aabbc4fbSShri Abhyankar   PetscFunctionBegin;
1016c98fd787SBarry Smith   /* force binary viewer to load .info file if it has not yet done so */
1017c98fd787SBarry Smith   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1018ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
1019aabbc4fbSShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1020aabbc4fbSShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"view must have one processor");
1021aabbc4fbSShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
1022aabbc4fbSShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
1023aabbc4fbSShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not matrix object");
1024aabbc4fbSShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
1025aabbc4fbSShri Abhyankar 
1026aabbc4fbSShri Abhyankar   /* set global size if not set already*/
1027aabbc4fbSShri Abhyankar   if (newmat->rmap->n < 0 && newmat->rmap->N < 0 && newmat->cmap->n < 0 && newmat->cmap->N < 0) {
1028aabbc4fbSShri Abhyankar     ierr = MatSetSizes(newmat,M,N,M,N);CHKERRQ(ierr);
1029aabbc4fbSShri Abhyankar   } else {
1030aabbc4fbSShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
1031aabbc4fbSShri Abhyankar     ierr = MatGetSize(newmat,&grows,&gcols);CHKERRQ(ierr);
1032aabbc4fbSShri 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);
1033aabbc4fbSShri Abhyankar   }
1034e6324fbbSBarry Smith   a = (Mat_SeqDense*)newmat->data;
1035e6324fbbSBarry Smith   if (!a->user_alloc) {
10360298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1037e6324fbbSBarry Smith   }
1038aabbc4fbSShri Abhyankar 
1039aabbc4fbSShri Abhyankar   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense */
1040aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
1041aabbc4fbSShri Abhyankar     v = a->v;
1042aabbc4fbSShri Abhyankar     /* Allocate some temp space to read in the values and then flip them
1043aabbc4fbSShri Abhyankar        from row major to column major */
1044854ce69bSBarry Smith     ierr = PetscMalloc1(M*N > 0 ? M*N : 1,&w);CHKERRQ(ierr);
1045aabbc4fbSShri Abhyankar     /* read in nonzero values */
1046aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,w,M*N,PETSC_SCALAR);CHKERRQ(ierr);
1047aabbc4fbSShri Abhyankar     /* now flip the values and store them in the matrix*/
1048aabbc4fbSShri Abhyankar     for (j=0; j<N; j++) {
1049aabbc4fbSShri Abhyankar       for (i=0; i<M; i++) {
1050aabbc4fbSShri Abhyankar         *v++ =w[i*N+j];
1051aabbc4fbSShri Abhyankar       }
1052aabbc4fbSShri Abhyankar     }
1053aabbc4fbSShri Abhyankar     ierr = PetscFree(w);CHKERRQ(ierr);
1054aabbc4fbSShri Abhyankar   } else {
1055aabbc4fbSShri Abhyankar     /* read row lengths */
1056854ce69bSBarry Smith     ierr = PetscMalloc1(M+1,&rowlengths);CHKERRQ(ierr);
1057aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
1058aabbc4fbSShri Abhyankar 
1059aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
1060aabbc4fbSShri Abhyankar     v = a->v;
1061aabbc4fbSShri Abhyankar 
1062aabbc4fbSShri Abhyankar     /* read column indices and nonzeros */
1063854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&scols);CHKERRQ(ierr);
1064aabbc4fbSShri Abhyankar     cols = scols;
1065aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT);CHKERRQ(ierr);
1066854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&svals);CHKERRQ(ierr);
1067aabbc4fbSShri Abhyankar     vals = svals;
1068aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR);CHKERRQ(ierr);
1069aabbc4fbSShri Abhyankar 
1070aabbc4fbSShri Abhyankar     /* insert into matrix */
1071aabbc4fbSShri Abhyankar     for (i=0; i<M; i++) {
1072aabbc4fbSShri Abhyankar       for (j=0; j<rowlengths[i]; j++) v[i+M*scols[j]] = svals[j];
1073aabbc4fbSShri Abhyankar       svals += rowlengths[i]; scols += rowlengths[i];
1074aabbc4fbSShri Abhyankar     }
1075aabbc4fbSShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1076aabbc4fbSShri Abhyankar     ierr = PetscFree(cols);CHKERRQ(ierr);
1077aabbc4fbSShri Abhyankar     ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1078aabbc4fbSShri Abhyankar   }
1079aabbc4fbSShri Abhyankar   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1080aabbc4fbSShri Abhyankar   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1081aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1082aabbc4fbSShri Abhyankar }
1083aabbc4fbSShri Abhyankar 
10846849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1085289bc588SBarry Smith {
1086932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1087dfbe8321SBarry Smith   PetscErrorCode    ierr;
108813f74950SBarry Smith   PetscInt          i,j;
10892dcb1b2aSMatthew Knepley   const char        *name;
109087828ca2SBarry Smith   PetscScalar       *v;
1091f3ef73ceSBarry Smith   PetscViewerFormat format;
10925f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1093ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
10945f481a85SSatish Balay #endif
1095932b0c3eSLois Curfman McInnes 
10963a40ed3dSBarry Smith   PetscFunctionBegin;
1097b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1098456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
10993a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1100fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1101d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1102d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
110344cd7ae7SLois Curfman McInnes       v    = a->v + i;
110477431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1105d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1106aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1107329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
110857622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1109329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
111057622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
11116831982aSBarry Smith         }
111280cd9d93SLois Curfman McInnes #else
11136831982aSBarry Smith         if (*v) {
111457622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
11156831982aSBarry Smith         }
111680cd9d93SLois Curfman McInnes #endif
11171b807ce4Svictorle         v += a->lda;
111880cd9d93SLois Curfman McInnes       }
1119b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
112080cd9d93SLois Curfman McInnes     }
1121d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
11223a40ed3dSBarry Smith   } else {
1123d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1124aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
112547989497SBarry Smith     /* determine if matrix has all real values */
112647989497SBarry Smith     v = a->v;
1127d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1128ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
112947989497SBarry Smith     }
113047989497SBarry Smith #endif
1131fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
11323a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1133d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1134d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1135fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1136ffac6cdbSBarry Smith     }
1137ffac6cdbSBarry Smith 
1138d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1139932b0c3eSLois Curfman McInnes       v = a->v + i;
1140d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1141aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
114247989497SBarry Smith         if (allreal) {
1143c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
114447989497SBarry Smith         } else {
1145c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
114647989497SBarry Smith         }
1147289bc588SBarry Smith #else
1148c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1149289bc588SBarry Smith #endif
11501b807ce4Svictorle         v += a->lda;
1151289bc588SBarry Smith       }
1152b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1153289bc588SBarry Smith     }
1154fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1155b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1156ffac6cdbSBarry Smith     }
1157d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1158da3a660dSBarry Smith   }
1159b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
11603a40ed3dSBarry Smith   PetscFunctionReturn(0);
1161289bc588SBarry Smith }
1162289bc588SBarry Smith 
11636849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_Binary(Mat A,PetscViewer viewer)
1164932b0c3eSLois Curfman McInnes {
1165932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
11666849ba73SBarry Smith   PetscErrorCode    ierr;
116713f74950SBarry Smith   int               fd;
1168d0f46423SBarry Smith   PetscInt          ict,j,n = A->cmap->n,m = A->rmap->n,i,*col_lens,nz = m*n;
1169f4403165SShri Abhyankar   PetscScalar       *v,*anonz,*vals;
1170f4403165SShri Abhyankar   PetscViewerFormat format;
1171932b0c3eSLois Curfman McInnes 
11723a40ed3dSBarry Smith   PetscFunctionBegin;
1173b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
117490ace30eSBarry Smith 
1175f4403165SShri Abhyankar   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1176f4403165SShri Abhyankar   if (format == PETSC_VIEWER_NATIVE) {
1177f4403165SShri Abhyankar     /* store the matrix as a dense matrix */
1178785e854fSJed Brown     ierr = PetscMalloc1(4,&col_lens);CHKERRQ(ierr);
11792205254eSKarl Rupp 
1180f4403165SShri Abhyankar     col_lens[0] = MAT_FILE_CLASSID;
1181f4403165SShri Abhyankar     col_lens[1] = m;
1182f4403165SShri Abhyankar     col_lens[2] = n;
1183f4403165SShri Abhyankar     col_lens[3] = MATRIX_BINARY_FORMAT_DENSE;
11842205254eSKarl Rupp 
1185f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,col_lens,4,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1186f4403165SShri Abhyankar     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1187f4403165SShri Abhyankar 
1188f4403165SShri Abhyankar     /* write out matrix, by rows */
1189854ce69bSBarry Smith     ierr = PetscMalloc1(m*n+1,&vals);CHKERRQ(ierr);
1190f4403165SShri Abhyankar     v    = a->v;
1191f4403165SShri Abhyankar     for (j=0; j<n; j++) {
1192f4403165SShri Abhyankar       for (i=0; i<m; i++) {
1193f4403165SShri Abhyankar         vals[j + i*n] = *v++;
1194f4403165SShri Abhyankar       }
1195f4403165SShri Abhyankar     }
1196f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,vals,n*m,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1197f4403165SShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1198f4403165SShri Abhyankar   } else {
1199854ce69bSBarry Smith     ierr = PetscMalloc1(4+nz,&col_lens);CHKERRQ(ierr);
12002205254eSKarl Rupp 
12010700a824SBarry Smith     col_lens[0] = MAT_FILE_CLASSID;
1202932b0c3eSLois Curfman McInnes     col_lens[1] = m;
1203932b0c3eSLois Curfman McInnes     col_lens[2] = n;
1204932b0c3eSLois Curfman McInnes     col_lens[3] = nz;
1205932b0c3eSLois Curfman McInnes 
1206932b0c3eSLois Curfman McInnes     /* store lengths of each row and write (including header) to file */
1207932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) col_lens[4+i] = n;
12086f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,4+m,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1209932b0c3eSLois Curfman McInnes 
1210932b0c3eSLois Curfman McInnes     /* Possibly should write in smaller increments, not whole matrix at once? */
1211932b0c3eSLois Curfman McInnes     /* store column indices (zero start index) */
1212932b0c3eSLois Curfman McInnes     ict = 0;
1213932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1214932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) col_lens[ict++] = j;
1215932b0c3eSLois Curfman McInnes     }
12166f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
1217606d414cSSatish Balay     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1218932b0c3eSLois Curfman McInnes 
1219932b0c3eSLois Curfman McInnes     /* store nonzero values */
1220854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&anonz);CHKERRQ(ierr);
1221932b0c3eSLois Curfman McInnes     ict  = 0;
1222932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1223932b0c3eSLois Curfman McInnes       v = a->v + i;
1224932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) {
12251b807ce4Svictorle         anonz[ict++] = *v; v += a->lda;
1226932b0c3eSLois Curfman McInnes       }
1227932b0c3eSLois Curfman McInnes     }
12286f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,anonz,nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1229606d414cSSatish Balay     ierr = PetscFree(anonz);CHKERRQ(ierr);
1230f4403165SShri Abhyankar   }
12313a40ed3dSBarry Smith   PetscFunctionReturn(0);
1232932b0c3eSLois Curfman McInnes }
1233932b0c3eSLois Curfman McInnes 
12349804daf3SBarry Smith #include <petscdraw.h>
1235e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1236f1af5d2fSBarry Smith {
1237f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
1238f1af5d2fSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
12396849ba73SBarry Smith   PetscErrorCode    ierr;
1240383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1241383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
124287828ca2SBarry Smith   PetscScalar       *v = a->v;
1243b0a32e0cSBarry Smith   PetscViewer       viewer;
1244b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1245f3ef73ceSBarry Smith   PetscViewerFormat format;
1246f1af5d2fSBarry Smith 
1247f1af5d2fSBarry Smith   PetscFunctionBegin;
1248f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1249b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1250b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1251f1af5d2fSBarry Smith 
1252f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1253383922c3SLisandro Dalcin 
1254fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1255383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1256f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1257f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1258383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1259f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1260f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1261f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1262329f5518SBarry Smith         if (PetscRealPart(v[j*m+i]) >  0.) {
1263b0a32e0cSBarry Smith           color = PETSC_DRAW_RED;
1264329f5518SBarry Smith         } else if (PetscRealPart(v[j*m+i]) <  0.) {
1265b0a32e0cSBarry Smith           color = PETSC_DRAW_BLUE;
1266f1af5d2fSBarry Smith         } else {
1267f1af5d2fSBarry Smith           continue;
1268f1af5d2fSBarry Smith         }
1269b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1270f1af5d2fSBarry Smith       }
1271f1af5d2fSBarry Smith     }
1272383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1273f1af5d2fSBarry Smith   } else {
1274f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1275f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1276b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1277b05fc000SLisandro Dalcin     PetscDraw popup;
1278b05fc000SLisandro Dalcin 
1279f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1280f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1281f1af5d2fSBarry Smith     }
1282383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1283b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
128445f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1285383922c3SLisandro Dalcin 
1286383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1287f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1288f1af5d2fSBarry Smith       x_l = j;
1289f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1290f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1291f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1292f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1293b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1294b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1295f1af5d2fSBarry Smith       }
1296f1af5d2fSBarry Smith     }
1297383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1298f1af5d2fSBarry Smith   }
1299f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1300f1af5d2fSBarry Smith }
1301f1af5d2fSBarry Smith 
1302e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1303f1af5d2fSBarry Smith {
1304b0a32e0cSBarry Smith   PetscDraw      draw;
1305ace3abfcSBarry Smith   PetscBool      isnull;
1306329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1307dfbe8321SBarry Smith   PetscErrorCode ierr;
1308f1af5d2fSBarry Smith 
1309f1af5d2fSBarry Smith   PetscFunctionBegin;
1310b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1311b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1312abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1313f1af5d2fSBarry Smith 
1314d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1315f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1316b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1317832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1318b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
13190298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1320832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1321f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1322f1af5d2fSBarry Smith }
1323f1af5d2fSBarry Smith 
1324dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1325932b0c3eSLois Curfman McInnes {
1326dfbe8321SBarry Smith   PetscErrorCode ierr;
1327ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1328932b0c3eSLois Curfman McInnes 
13293a40ed3dSBarry Smith   PetscFunctionBegin;
1330251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1331251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1332251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
13330f5bd95cSBarry Smith 
1334c45a1595SBarry Smith   if (iascii) {
1335c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
13360f5bd95cSBarry Smith   } else if (isbinary) {
13373a40ed3dSBarry Smith     ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr);
1338f1af5d2fSBarry Smith   } else if (isdraw) {
1339f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1340932b0c3eSLois Curfman McInnes   }
13413a40ed3dSBarry Smith   PetscFunctionReturn(0);
1342932b0c3eSLois Curfman McInnes }
1343289bc588SBarry Smith 
1344e0877f53SBarry Smith static PetscErrorCode MatDestroy_SeqDense(Mat mat)
1345289bc588SBarry Smith {
1346ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1347dfbe8321SBarry Smith   PetscErrorCode ierr;
134890f02eecSBarry Smith 
13493a40ed3dSBarry Smith   PetscFunctionBegin;
1350aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1351d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1352a5a9c739SBarry Smith #endif
135305b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1354a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1355abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
13566857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1357bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1358dbd8c25aSHong Zhang 
1359dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
1360bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
1361bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
13628baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
13638baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
13648baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
13658baccfbdSHong Zhang #endif
1366bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
1367bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1368bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1369bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1370abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatPtAP_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
13713bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
13723bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
13733bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
13743a40ed3dSBarry Smith   PetscFunctionReturn(0);
1375289bc588SBarry Smith }
1376289bc588SBarry Smith 
1377e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1378289bc588SBarry Smith {
1379c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
13806849ba73SBarry Smith   PetscErrorCode ierr;
138113f74950SBarry Smith   PetscInt       k,j,m,n,M;
138287828ca2SBarry Smith   PetscScalar    *v,tmp;
138348b35521SBarry Smith 
13843a40ed3dSBarry Smith   PetscFunctionBegin;
1385d0f46423SBarry Smith   v = mat->v; m = A->rmap->n; M = mat->lda; n = A->cmap->n;
1386cf37664fSBarry Smith   if (reuse == MAT_INPLACE_MATRIX) { /* in place transpose */
1387e7e72b3dSBarry Smith     if (m != n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can not transpose non-square matrix in place");
1388e7e72b3dSBarry Smith     else {
1389d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1390289bc588SBarry Smith         for (k=0; k<j; k++) {
13911b807ce4Svictorle           tmp        = v[j + k*M];
13921b807ce4Svictorle           v[j + k*M] = v[k + j*M];
13931b807ce4Svictorle           v[k + j*M] = tmp;
1394289bc588SBarry Smith         }
1395289bc588SBarry Smith       }
1396d64ed03dSBarry Smith     }
13973a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1398d3e5ee88SLois Curfman McInnes     Mat          tmat;
1399ec8511deSBarry Smith     Mat_SeqDense *tmatd;
140087828ca2SBarry Smith     PetscScalar  *v2;
1401af36a384SStefano Zampini     PetscInt     M2;
1402ea709b57SSatish Balay 
1403fc4dec0aSBarry Smith     if (reuse == MAT_INITIAL_MATRIX) {
1404ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1405d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
14067adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
14070298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1408fc4dec0aSBarry Smith     } else {
1409fc4dec0aSBarry Smith       tmat = *matout;
1410fc4dec0aSBarry Smith     }
1411ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1412af36a384SStefano Zampini     v = mat->v; v2 = tmatd->v; M2 = tmatd->lda;
1413d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1414af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1415d3e5ee88SLois Curfman McInnes     }
14166d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14176d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1418d3e5ee88SLois Curfman McInnes     *matout = tmat;
141948b35521SBarry Smith   }
14203a40ed3dSBarry Smith   PetscFunctionReturn(0);
1421289bc588SBarry Smith }
1422289bc588SBarry Smith 
1423e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1424289bc588SBarry Smith {
1425c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat1 = (Mat_SeqDense*)A1->data;
1426c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat2 = (Mat_SeqDense*)A2->data;
142713f74950SBarry Smith   PetscInt     i,j;
1428a2ea699eSBarry Smith   PetscScalar  *v1,*v2;
14299ea5d5aeSSatish Balay 
14303a40ed3dSBarry Smith   PetscFunctionBegin;
1431d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1432d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1433d0f46423SBarry Smith   for (i=0; i<A1->rmap->n; i++) {
14341b807ce4Svictorle     v1 = mat1->v+i; v2 = mat2->v+i;
1435d0f46423SBarry Smith     for (j=0; j<A1->cmap->n; j++) {
14363a40ed3dSBarry Smith       if (*v1 != *v2) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
14371b807ce4Svictorle       v1 += mat1->lda; v2 += mat2->lda;
14381b807ce4Svictorle     }
1439289bc588SBarry Smith   }
144077c4ece6SBarry Smith   *flg = PETSC_TRUE;
14413a40ed3dSBarry Smith   PetscFunctionReturn(0);
1442289bc588SBarry Smith }
1443289bc588SBarry Smith 
1444e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1445289bc588SBarry Smith {
1446c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
1447dfbe8321SBarry Smith   PetscErrorCode ierr;
144813f74950SBarry Smith   PetscInt       i,n,len;
144987828ca2SBarry Smith   PetscScalar    *x,zero = 0.0;
145044cd7ae7SLois Curfman McInnes 
14513a40ed3dSBarry Smith   PetscFunctionBegin;
14522dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
14537a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
14541ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1455d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1456e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
145744cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
14581b807ce4Svictorle     x[i] = mat->v[i*mat->lda + i];
1459289bc588SBarry Smith   }
14601ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
14613a40ed3dSBarry Smith   PetscFunctionReturn(0);
1462289bc588SBarry Smith }
1463289bc588SBarry Smith 
1464e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1465289bc588SBarry Smith {
1466c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1467f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1468f1ceaac6SMatthew G. Knepley   PetscScalar       x,*v;
1469dfbe8321SBarry Smith   PetscErrorCode    ierr;
1470d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
147155659b69SBarry Smith 
14723a40ed3dSBarry Smith   PetscFunctionBegin;
147328988994SBarry Smith   if (ll) {
14747a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1475f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1476e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1477da3a660dSBarry Smith     for (i=0; i<m; i++) {
1478da3a660dSBarry Smith       x = l[i];
1479da3a660dSBarry Smith       v = mat->v + i;
1480b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1481da3a660dSBarry Smith     }
1482f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1483eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1484da3a660dSBarry Smith   }
148528988994SBarry Smith   if (rr) {
14867a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1487f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1488e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1489da3a660dSBarry Smith     for (i=0; i<n; i++) {
1490da3a660dSBarry Smith       x = r[i];
1491b43bac26SStefano Zampini       v = mat->v + i*mat->lda;
14922205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1493da3a660dSBarry Smith     }
1494f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1495eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1496da3a660dSBarry Smith   }
14973a40ed3dSBarry Smith   PetscFunctionReturn(0);
1498289bc588SBarry Smith }
1499289bc588SBarry Smith 
1500e0877f53SBarry Smith static PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1501289bc588SBarry Smith {
1502c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
150387828ca2SBarry Smith   PetscScalar    *v   = mat->v;
1504329f5518SBarry Smith   PetscReal      sum  = 0.0;
1505d0f46423SBarry Smith   PetscInt       lda  =mat->lda,m=A->rmap->n,i,j;
1506efee365bSSatish Balay   PetscErrorCode ierr;
150755659b69SBarry Smith 
15083a40ed3dSBarry Smith   PetscFunctionBegin;
1509289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1510a5ce6ee0Svictorle     if (lda>m) {
1511d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1512a5ce6ee0Svictorle         v = mat->v+j*lda;
1513a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1514a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1515a5ce6ee0Svictorle         }
1516a5ce6ee0Svictorle       }
1517a5ce6ee0Svictorle     } else {
1518570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1519570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1520570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1521570b7f6dSBarry Smith     }
1522570b7f6dSBarry Smith #else
1523d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1524329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1525289bc588SBarry Smith       }
1526a5ce6ee0Svictorle     }
15278f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1528570b7f6dSBarry Smith #endif
1529dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
15303a40ed3dSBarry Smith   } else if (type == NORM_1) {
1531064f8208SBarry Smith     *nrm = 0.0;
1532d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
15331b807ce4Svictorle       v   = mat->v + j*mat->lda;
1534289bc588SBarry Smith       sum = 0.0;
1535d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
153633a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1537289bc588SBarry Smith       }
1538064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1539289bc588SBarry Smith     }
1540eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
15413a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1542064f8208SBarry Smith     *nrm = 0.0;
1543d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1544289bc588SBarry Smith       v   = mat->v + j;
1545289bc588SBarry Smith       sum = 0.0;
1546d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
15471b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1548289bc588SBarry Smith       }
1549064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1550289bc588SBarry Smith     }
1551eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1552e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
15533a40ed3dSBarry Smith   PetscFunctionReturn(0);
1554289bc588SBarry Smith }
1555289bc588SBarry Smith 
1556e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1557289bc588SBarry Smith {
1558c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
155963ba0a88SBarry Smith   PetscErrorCode ierr;
156067e560aaSBarry Smith 
15613a40ed3dSBarry Smith   PetscFunctionBegin;
1562b5a2b587SKris Buschelman   switch (op) {
1563b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
15644e0d8c25SBarry Smith     aij->roworiented = flg;
1565b5a2b587SKris Buschelman     break;
1566512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1567b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
15683971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
15694e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
157013fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1571b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1572b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
15735021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
15745021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
15755021d80fSJed Brown     break;
15765021d80fSJed Brown   case MAT_SPD:
157777e54ba9SKris Buschelman   case MAT_SYMMETRIC:
157877e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
15799a4540c5SBarry Smith   case MAT_HERMITIAN:
15809a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
15815021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
158277e54ba9SKris Buschelman     break;
1583b5a2b587SKris Buschelman   default:
1584e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
15853a40ed3dSBarry Smith   }
15863a40ed3dSBarry Smith   PetscFunctionReturn(0);
1587289bc588SBarry Smith }
1588289bc588SBarry Smith 
1589e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
15906f0a148fSBarry Smith {
1591ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
15926849ba73SBarry Smith   PetscErrorCode ierr;
1593d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
15943a40ed3dSBarry Smith 
15953a40ed3dSBarry Smith   PetscFunctionBegin;
1596a5ce6ee0Svictorle   if (lda>m) {
1597d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1598a5ce6ee0Svictorle       ierr = PetscMemzero(l->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr);
1599a5ce6ee0Svictorle     }
1600a5ce6ee0Svictorle   } else {
1601d0f46423SBarry Smith     ierr = PetscMemzero(l->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
1602a5ce6ee0Svictorle   }
16033a40ed3dSBarry Smith   PetscFunctionReturn(0);
16046f0a148fSBarry Smith }
16056f0a148fSBarry Smith 
1606e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
16076f0a148fSBarry Smith {
160897b48c8fSBarry Smith   PetscErrorCode    ierr;
1609ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1610b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
161197b48c8fSBarry Smith   PetscScalar       *slot,*bb;
161297b48c8fSBarry Smith   const PetscScalar *xx;
161355659b69SBarry Smith 
16143a40ed3dSBarry Smith   PetscFunctionBegin;
1615b9679d65SBarry Smith #if defined(PETSC_USE_DEBUG)
1616b9679d65SBarry Smith   for (i=0; i<N; i++) {
1617b9679d65SBarry Smith     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1618b9679d65SBarry 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);
1619b9679d65SBarry Smith   }
1620b9679d65SBarry Smith #endif
1621b9679d65SBarry Smith 
162297b48c8fSBarry Smith   /* fix right hand side if needed */
162397b48c8fSBarry Smith   if (x && b) {
162497b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
162597b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
16262205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
162797b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
162897b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
162997b48c8fSBarry Smith   }
163097b48c8fSBarry Smith 
16316f0a148fSBarry Smith   for (i=0; i<N; i++) {
16326f0a148fSBarry Smith     slot = l->v + rows[i];
1633b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
16346f0a148fSBarry Smith   }
1635f4df32b1SMatthew Knepley   if (diag != 0.0) {
1636b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
16376f0a148fSBarry Smith     for (i=0; i<N; i++) {
1638b9679d65SBarry Smith       slot  = l->v + (m+1)*rows[i];
1639f4df32b1SMatthew Knepley       *slot = diag;
16406f0a148fSBarry Smith     }
16416f0a148fSBarry Smith   }
16423a40ed3dSBarry Smith   PetscFunctionReturn(0);
16436f0a148fSBarry Smith }
1644557bce09SLois Curfman McInnes 
1645e0877f53SBarry Smith static PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar *array[])
164664e87e97SBarry Smith {
1647c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
16483a40ed3dSBarry Smith 
16493a40ed3dSBarry Smith   PetscFunctionBegin;
1650e32f2f54SBarry 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");
165164e87e97SBarry Smith   *array = mat->v;
16523a40ed3dSBarry Smith   PetscFunctionReturn(0);
165364e87e97SBarry Smith }
16540754003eSLois Curfman McInnes 
1655e0877f53SBarry Smith static PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar *array[])
1656ff14e315SSatish Balay {
16573a40ed3dSBarry Smith   PetscFunctionBegin;
165809b544d4SBarry Smith   *array = 0; /* user cannot accidently use the array later */
16593a40ed3dSBarry Smith   PetscFunctionReturn(0);
1660ff14e315SSatish Balay }
16610754003eSLois Curfman McInnes 
1662dec5eb66SMatthew G Knepley /*@C
16638c778c55SBarry Smith    MatDenseGetArray - gives access to the array where the data for a SeqDense matrix is stored
166473a71a0fSBarry Smith 
166573a71a0fSBarry Smith    Not Collective
166673a71a0fSBarry Smith 
166773a71a0fSBarry Smith    Input Parameter:
1668579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
166973a71a0fSBarry Smith 
167073a71a0fSBarry Smith    Output Parameter:
167173a71a0fSBarry Smith .   array - pointer to the data
167273a71a0fSBarry Smith 
167373a71a0fSBarry Smith    Level: intermediate
167473a71a0fSBarry Smith 
16758c778c55SBarry Smith .seealso: MatDenseRestoreArray()
167673a71a0fSBarry Smith @*/
16778c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
167873a71a0fSBarry Smith {
167973a71a0fSBarry Smith   PetscErrorCode ierr;
168073a71a0fSBarry Smith 
168173a71a0fSBarry Smith   PetscFunctionBegin;
16828c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
168373a71a0fSBarry Smith   PetscFunctionReturn(0);
168473a71a0fSBarry Smith }
168573a71a0fSBarry Smith 
1686dec5eb66SMatthew G Knepley /*@C
1687579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
168873a71a0fSBarry Smith 
168973a71a0fSBarry Smith    Not Collective
169073a71a0fSBarry Smith 
169173a71a0fSBarry Smith    Input Parameters:
1692579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
169373a71a0fSBarry Smith .  array - pointer to the data
169473a71a0fSBarry Smith 
169573a71a0fSBarry Smith    Level: intermediate
169673a71a0fSBarry Smith 
16978c778c55SBarry Smith .seealso: MatDenseGetArray()
169873a71a0fSBarry Smith @*/
16998c778c55SBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
170073a71a0fSBarry Smith {
170173a71a0fSBarry Smith   PetscErrorCode ierr;
170273a71a0fSBarry Smith 
170373a71a0fSBarry Smith   PetscFunctionBegin;
17048c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
170573a71a0fSBarry Smith   PetscFunctionReturn(0);
170673a71a0fSBarry Smith }
170773a71a0fSBarry Smith 
17087dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
17090754003eSLois Curfman McInnes {
1710c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
17116849ba73SBarry Smith   PetscErrorCode ierr;
17125d0c19d7SBarry Smith   PetscInt       i,j,nrows,ncols;
17135d0c19d7SBarry Smith   const PetscInt *irow,*icol;
171487828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
17150754003eSLois Curfman McInnes   Mat            newmat;
17160754003eSLois Curfman McInnes 
17173a40ed3dSBarry Smith   PetscFunctionBegin;
171878b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
171978b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1720e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1721e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
17220754003eSLois Curfman McInnes 
1723182d2002SSatish Balay   /* Check submatrixcall */
1724182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
172513f74950SBarry Smith     PetscInt n_cols,n_rows;
1726182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
172721a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
1728f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
1729c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
173021a2c019SBarry Smith     }
1731182d2002SSatish Balay     newmat = *B;
1732182d2002SSatish Balay   } else {
17330754003eSLois Curfman McInnes     /* Create and fill new matrix */
1734ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
1735f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
17367adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
17370298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1738182d2002SSatish Balay   }
1739182d2002SSatish Balay 
1740182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1741182d2002SSatish Balay   bv = ((Mat_SeqDense*)newmat->data)->v;
1742182d2002SSatish Balay 
1743182d2002SSatish Balay   for (i=0; i<ncols; i++) {
17446de62eeeSBarry Smith     av = v + mat->lda*icol[i];
17452205254eSKarl Rupp     for (j=0; j<nrows; j++) *bv++ = av[irow[j]];
17460754003eSLois Curfman McInnes   }
1747182d2002SSatish Balay 
1748182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
17496d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17506d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17510754003eSLois Curfman McInnes 
17520754003eSLois Curfman McInnes   /* Free work space */
175378b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
175478b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1755182d2002SSatish Balay   *B   = newmat;
17563a40ed3dSBarry Smith   PetscFunctionReturn(0);
17570754003eSLois Curfman McInnes }
17580754003eSLois Curfman McInnes 
17597dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1760905e6a2fSBarry Smith {
17616849ba73SBarry Smith   PetscErrorCode ierr;
176213f74950SBarry Smith   PetscInt       i;
1763905e6a2fSBarry Smith 
17643a40ed3dSBarry Smith   PetscFunctionBegin;
1765905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1766df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
1767905e6a2fSBarry Smith   }
1768905e6a2fSBarry Smith 
1769905e6a2fSBarry Smith   for (i=0; i<n; i++) {
17707dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1771905e6a2fSBarry Smith   }
17723a40ed3dSBarry Smith   PetscFunctionReturn(0);
1773905e6a2fSBarry Smith }
1774905e6a2fSBarry Smith 
1775e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
1776c0aa2d19SHong Zhang {
1777c0aa2d19SHong Zhang   PetscFunctionBegin;
1778c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1779c0aa2d19SHong Zhang }
1780c0aa2d19SHong Zhang 
1781e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
1782c0aa2d19SHong Zhang {
1783c0aa2d19SHong Zhang   PetscFunctionBegin;
1784c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1785c0aa2d19SHong Zhang }
1786c0aa2d19SHong Zhang 
1787e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
17884b0e389bSBarry Smith {
17894b0e389bSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
17906849ba73SBarry Smith   PetscErrorCode ierr;
1791d0f46423SBarry Smith   PetscInt       lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
17923a40ed3dSBarry Smith 
17933a40ed3dSBarry Smith   PetscFunctionBegin;
179433f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
179533f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
1796cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
17973a40ed3dSBarry Smith     PetscFunctionReturn(0);
17983a40ed3dSBarry Smith   }
1799e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
1800a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
18010dbb7854Svictorle     for (j=0; j<n; j++) {
1802a5ce6ee0Svictorle       ierr = PetscMemcpy(b->v+j*lda2,a->v+j*lda1,m*sizeof(PetscScalar));CHKERRQ(ierr);
1803a5ce6ee0Svictorle     }
1804a5ce6ee0Svictorle   } else {
1805d0f46423SBarry Smith     ierr = PetscMemcpy(b->v,a->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
1806a5ce6ee0Svictorle   }
1807273d9f13SBarry Smith   PetscFunctionReturn(0);
1808273d9f13SBarry Smith }
1809273d9f13SBarry Smith 
1810e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
1811273d9f13SBarry Smith {
1812dfbe8321SBarry Smith   PetscErrorCode ierr;
1813273d9f13SBarry Smith 
1814273d9f13SBarry Smith   PetscFunctionBegin;
1815273d9f13SBarry Smith   ierr =  MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
18163a40ed3dSBarry Smith   PetscFunctionReturn(0);
18174b0e389bSBarry Smith }
18184b0e389bSBarry Smith 
1819ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
1820ba337c44SJed Brown {
1821ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1822ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1823ba337c44SJed Brown   PetscScalar  *aa = a->v;
1824ba337c44SJed Brown 
1825ba337c44SJed Brown   PetscFunctionBegin;
1826ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
1827ba337c44SJed Brown   PetscFunctionReturn(0);
1828ba337c44SJed Brown }
1829ba337c44SJed Brown 
1830ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
1831ba337c44SJed Brown {
1832ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1833ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1834ba337c44SJed Brown   PetscScalar  *aa = a->v;
1835ba337c44SJed Brown 
1836ba337c44SJed Brown   PetscFunctionBegin;
1837ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
1838ba337c44SJed Brown   PetscFunctionReturn(0);
1839ba337c44SJed Brown }
1840ba337c44SJed Brown 
1841ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
1842ba337c44SJed Brown {
1843ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1844ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1845ba337c44SJed Brown   PetscScalar  *aa = a->v;
1846ba337c44SJed Brown 
1847ba337c44SJed Brown   PetscFunctionBegin;
1848ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1849ba337c44SJed Brown   PetscFunctionReturn(0);
1850ba337c44SJed Brown }
1851284134d9SBarry Smith 
1852a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
1853150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
1854a9fe9ddaSSatish Balay {
1855a9fe9ddaSSatish Balay   PetscErrorCode ierr;
1856a9fe9ddaSSatish Balay 
1857a9fe9ddaSSatish Balay   PetscFunctionBegin;
1858a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
18593ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
1860a9fe9ddaSSatish Balay     ierr = MatMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
18613ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
1862a9fe9ddaSSatish Balay   }
18633ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
1864a9fe9ddaSSatish Balay   ierr = MatMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
18653ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
1866a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1867a9fe9ddaSSatish Balay }
1868a9fe9ddaSSatish Balay 
1869a9fe9ddaSSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
1870a9fe9ddaSSatish Balay {
1871ee16a9a1SHong Zhang   PetscErrorCode ierr;
1872d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
1873ee16a9a1SHong Zhang   Mat            Cmat;
1874a9fe9ddaSSatish Balay 
1875ee16a9a1SHong Zhang   PetscFunctionBegin;
1876e32f2f54SBarry 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);
1877ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
1878ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
1879ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
18800298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
1881d73949e8SHong Zhang 
1882ee16a9a1SHong Zhang   *C = Cmat;
1883ee16a9a1SHong Zhang   PetscFunctionReturn(0);
1884ee16a9a1SHong Zhang }
1885a9fe9ddaSSatish Balay 
1886a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
1887a9fe9ddaSSatish Balay {
1888a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1889a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
1890a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
18910805154bSBarry Smith   PetscBLASInt   m,n,k;
1892a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
1893c5df96a5SBarry Smith   PetscErrorCode ierr;
1894fd4e9aacSBarry Smith   PetscBool      flg;
1895a9fe9ddaSSatish Balay 
1896a9fe9ddaSSatish Balay   PetscFunctionBegin;
1897fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQDENSE,&flg);CHKERRQ(ierr);
1898fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Second matrix must be dense");
1899fd4e9aacSBarry Smith 
1900fd4e9aacSBarry Smith   /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/
1901fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
1902fd4e9aacSBarry Smith   if (flg) {
1903fd4e9aacSBarry Smith     C->ops->matmultnumeric = MatMatMultNumeric_SeqAIJ_SeqDense;
1904fd4e9aacSBarry Smith     ierr = (*C->ops->matmultnumeric)(A,B,C);CHKERRQ(ierr);
1905fd4e9aacSBarry Smith     PetscFunctionReturn(0);
1906fd4e9aacSBarry Smith   }
1907fd4e9aacSBarry Smith 
1908fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&flg);CHKERRQ(ierr);
1909fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"First matrix must be dense");
19108208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
19118208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
1912c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
19135ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
1914a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1915a9fe9ddaSSatish Balay }
1916a9fe9ddaSSatish Balay 
191775648e8dSHong Zhang PetscErrorCode MatTransposeMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
1918a9fe9ddaSSatish Balay {
1919a9fe9ddaSSatish Balay   PetscErrorCode ierr;
1920a9fe9ddaSSatish Balay 
1921a9fe9ddaSSatish Balay   PetscFunctionBegin;
1922a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
19233ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
192475648e8dSHong Zhang     ierr = MatTransposeMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
19253ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
1926a9fe9ddaSSatish Balay   }
19273ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
192875648e8dSHong Zhang   ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
19293ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
1930a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1931a9fe9ddaSSatish Balay }
1932a9fe9ddaSSatish Balay 
193375648e8dSHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
1934a9fe9ddaSSatish Balay {
1935ee16a9a1SHong Zhang   PetscErrorCode ierr;
1936d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
1937ee16a9a1SHong Zhang   Mat            Cmat;
1938a9fe9ddaSSatish Balay 
1939ee16a9a1SHong Zhang   PetscFunctionBegin;
1940e32f2f54SBarry 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);
1941ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
1942ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
1943ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
19440298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
19452205254eSKarl Rupp 
1946ee16a9a1SHong Zhang   Cmat->assembled = PETSC_TRUE;
19472205254eSKarl Rupp 
1948ee16a9a1SHong Zhang   *C = Cmat;
1949ee16a9a1SHong Zhang   PetscFunctionReturn(0);
1950ee16a9a1SHong Zhang }
1951a9fe9ddaSSatish Balay 
195275648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
1953a9fe9ddaSSatish Balay {
1954a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1955a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
1956a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
19570805154bSBarry Smith   PetscBLASInt   m,n,k;
1958a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
1959c5df96a5SBarry Smith   PetscErrorCode ierr;
1960a9fe9ddaSSatish Balay 
1961a9fe9ddaSSatish Balay   PetscFunctionBegin;
19628208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
19638208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
1964c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
19655ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
1966a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1967a9fe9ddaSSatish Balay }
1968985db425SBarry Smith 
1969e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
1970985db425SBarry Smith {
1971985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1972985db425SBarry Smith   PetscErrorCode ierr;
1973d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
1974985db425SBarry Smith   PetscScalar    *x;
1975985db425SBarry Smith   MatScalar      *aa = a->v;
1976985db425SBarry Smith 
1977985db425SBarry Smith   PetscFunctionBegin;
1978e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1979985db425SBarry Smith 
1980985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
1981985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1982985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
1983e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1984985db425SBarry Smith   for (i=0; i<m; i++) {
1985985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
1986985db425SBarry Smith     for (j=1; j<n; j++) {
1987985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
1988985db425SBarry Smith     }
1989985db425SBarry Smith   }
1990985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
1991985db425SBarry Smith   PetscFunctionReturn(0);
1992985db425SBarry Smith }
1993985db425SBarry Smith 
1994e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
1995985db425SBarry Smith {
1996985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1997985db425SBarry Smith   PetscErrorCode ierr;
1998d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
1999985db425SBarry Smith   PetscScalar    *x;
2000985db425SBarry Smith   PetscReal      atmp;
2001985db425SBarry Smith   MatScalar      *aa = a->v;
2002985db425SBarry Smith 
2003985db425SBarry Smith   PetscFunctionBegin;
2004e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2005985db425SBarry Smith 
2006985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2007985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2008985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2009e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2010985db425SBarry Smith   for (i=0; i<m; i++) {
20119189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2012985db425SBarry Smith     for (j=1; j<n; j++) {
2013985db425SBarry Smith       atmp = PetscAbsScalar(aa[i+m*j]);
2014985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2015985db425SBarry Smith     }
2016985db425SBarry Smith   }
2017985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2018985db425SBarry Smith   PetscFunctionReturn(0);
2019985db425SBarry Smith }
2020985db425SBarry Smith 
2021e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2022985db425SBarry Smith {
2023985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2024985db425SBarry Smith   PetscErrorCode ierr;
2025d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
2026985db425SBarry Smith   PetscScalar    *x;
2027985db425SBarry Smith   MatScalar      *aa = a->v;
2028985db425SBarry Smith 
2029985db425SBarry Smith   PetscFunctionBegin;
2030e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2031985db425SBarry Smith 
2032985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2033985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2034985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2035e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2036985db425SBarry Smith   for (i=0; i<m; i++) {
2037985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2038985db425SBarry Smith     for (j=1; j<n; j++) {
2039985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
2040985db425SBarry Smith     }
2041985db425SBarry Smith   }
2042985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2043985db425SBarry Smith   PetscFunctionReturn(0);
2044985db425SBarry Smith }
2045985db425SBarry Smith 
2046e0877f53SBarry Smith static PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
20478d0534beSBarry Smith {
20488d0534beSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
20498d0534beSBarry Smith   PetscErrorCode ierr;
20508d0534beSBarry Smith   PetscScalar    *x;
20518d0534beSBarry Smith 
20528d0534beSBarry Smith   PetscFunctionBegin;
2053e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
20548d0534beSBarry Smith 
20558d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2056d0f46423SBarry Smith   ierr = PetscMemcpy(x,a->v+col*a->lda,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
20578d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
20588d0534beSBarry Smith   PetscFunctionReturn(0);
20598d0534beSBarry Smith }
20608d0534beSBarry Smith 
20610716a85fSBarry Smith 
20620716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
20630716a85fSBarry Smith {
20640716a85fSBarry Smith   PetscErrorCode ierr;
20650716a85fSBarry Smith   PetscInt       i,j,m,n;
20660716a85fSBarry Smith   PetscScalar    *a;
20670716a85fSBarry Smith 
20680716a85fSBarry Smith   PetscFunctionBegin;
20690716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
20700716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
20718c778c55SBarry Smith   ierr = MatDenseGetArray(A,&a);CHKERRQ(ierr);
20720716a85fSBarry Smith   if (type == NORM_2) {
20730716a85fSBarry Smith     for (i=0; i<n; i++) {
20740716a85fSBarry Smith       for (j=0; j<m; j++) {
20750716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
20760716a85fSBarry Smith       }
20770716a85fSBarry Smith       a += m;
20780716a85fSBarry Smith     }
20790716a85fSBarry Smith   } else if (type == NORM_1) {
20800716a85fSBarry Smith     for (i=0; i<n; i++) {
20810716a85fSBarry Smith       for (j=0; j<m; j++) {
20820716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
20830716a85fSBarry Smith       }
20840716a85fSBarry Smith       a += m;
20850716a85fSBarry Smith     }
20860716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
20870716a85fSBarry Smith     for (i=0; i<n; i++) {
20880716a85fSBarry Smith       for (j=0; j<m; j++) {
20890716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
20900716a85fSBarry Smith       }
20910716a85fSBarry Smith       a += m;
20920716a85fSBarry Smith     }
2093ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
20948c778c55SBarry Smith   ierr = MatDenseRestoreArray(A,&a);CHKERRQ(ierr);
20950716a85fSBarry Smith   if (type == NORM_2) {
20968f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
20970716a85fSBarry Smith   }
20980716a85fSBarry Smith   PetscFunctionReturn(0);
20990716a85fSBarry Smith }
21000716a85fSBarry Smith 
210173a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
210273a71a0fSBarry Smith {
210373a71a0fSBarry Smith   PetscErrorCode ierr;
210473a71a0fSBarry Smith   PetscScalar    *a;
210573a71a0fSBarry Smith   PetscInt       m,n,i;
210673a71a0fSBarry Smith 
210773a71a0fSBarry Smith   PetscFunctionBegin;
210873a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
21098c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
211073a71a0fSBarry Smith   for (i=0; i<m*n; i++) {
211173a71a0fSBarry Smith     ierr = PetscRandomGetValue(rctx,a+i);CHKERRQ(ierr);
211273a71a0fSBarry Smith   }
21138c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
211473a71a0fSBarry Smith   PetscFunctionReturn(0);
211573a71a0fSBarry Smith }
211673a71a0fSBarry Smith 
21173b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
21183b49f96aSBarry Smith {
21193b49f96aSBarry Smith   PetscFunctionBegin;
21203b49f96aSBarry Smith   *missing = PETSC_FALSE;
21213b49f96aSBarry Smith   PetscFunctionReturn(0);
21223b49f96aSBarry Smith }
212373a71a0fSBarry Smith 
2124abc3b08eSStefano Zampini 
2125289bc588SBarry Smith /* -------------------------------------------------------------------*/
2126a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2127905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2128905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2129905e6a2fSBarry Smith                                         MatMult_SeqDense,
213097304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
21317c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
21327c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2133db4efbfdSBarry Smith                                         0,
2134db4efbfdSBarry Smith                                         0,
2135db4efbfdSBarry Smith                                         0,
2136db4efbfdSBarry Smith                                 /* 10*/ 0,
2137905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2138905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
213941f059aeSBarry Smith                                         MatSOR_SeqDense,
2140ec8511deSBarry Smith                                         MatTranspose_SeqDense,
214197304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2142905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2143905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2144905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2145905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2146c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2147c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2148905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2149905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2150d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2151db4efbfdSBarry Smith                                         0,
2152db4efbfdSBarry Smith                                         0,
2153db4efbfdSBarry Smith                                         0,
2154db4efbfdSBarry Smith                                         0,
21554994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2156273d9f13SBarry Smith                                         0,
2157905e6a2fSBarry Smith                                         0,
215873a71a0fSBarry Smith                                         0,
215973a71a0fSBarry Smith                                         0,
2160d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2161a5ae1ecdSBarry Smith                                         0,
2162a5ae1ecdSBarry Smith                                         0,
2163a5ae1ecdSBarry Smith                                         0,
2164a5ae1ecdSBarry Smith                                         0,
2165d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
21667dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2167a5ae1ecdSBarry Smith                                         0,
21684b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2169a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2170d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2171a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
21727d68702bSBarry Smith                                         MatShift_Basic,
2173a5ae1ecdSBarry Smith                                         0,
21743f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
217573a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2176a5ae1ecdSBarry Smith                                         0,
2177a5ae1ecdSBarry Smith                                         0,
2178a5ae1ecdSBarry Smith                                         0,
2179a5ae1ecdSBarry Smith                                         0,
2180d519adbfSMatthew Knepley                                 /* 54*/ 0,
2181a5ae1ecdSBarry Smith                                         0,
2182a5ae1ecdSBarry Smith                                         0,
2183a5ae1ecdSBarry Smith                                         0,
2184a5ae1ecdSBarry Smith                                         0,
2185d519adbfSMatthew Knepley                                 /* 59*/ 0,
2186e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2187e03a110bSBarry Smith                                         MatView_SeqDense,
2188357abbc8SBarry Smith                                         0,
218997304618SKris Buschelman                                         0,
2190d519adbfSMatthew Knepley                                 /* 64*/ 0,
219197304618SKris Buschelman                                         0,
219297304618SKris Buschelman                                         0,
219397304618SKris Buschelman                                         0,
219497304618SKris Buschelman                                         0,
2195d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
219697304618SKris Buschelman                                         0,
219797304618SKris Buschelman                                         0,
219897304618SKris Buschelman                                         0,
219997304618SKris Buschelman                                         0,
2200d519adbfSMatthew Knepley                                 /* 74*/ 0,
220197304618SKris Buschelman                                         0,
220297304618SKris Buschelman                                         0,
220397304618SKris Buschelman                                         0,
220497304618SKris Buschelman                                         0,
2205d519adbfSMatthew Knepley                                 /* 79*/ 0,
220697304618SKris Buschelman                                         0,
220797304618SKris Buschelman                                         0,
220897304618SKris Buschelman                                         0,
22095bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2210865e5f61SKris Buschelman                                         0,
22111cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2212865e5f61SKris Buschelman                                         0,
2213865e5f61SKris Buschelman                                         0,
2214865e5f61SKris Buschelman                                         0,
2215d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqDense_SeqDense,
2216a9fe9ddaSSatish Balay                                         MatMatMultSymbolic_SeqDense_SeqDense,
2217a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2218abc3b08eSStefano Zampini                                         MatPtAP_SeqDense_SeqDense,
2219abc3b08eSStefano Zampini                                         MatPtAPSymbolic_SeqDense_SeqDense,
2220abc3b08eSStefano Zampini                                 /* 94*/ MatPtAPNumeric_SeqDense_SeqDense,
22215df89d91SHong Zhang                                         0,
22225df89d91SHong Zhang                                         0,
22235df89d91SHong Zhang                                         0,
2224284134d9SBarry Smith                                         0,
2225d519adbfSMatthew Knepley                                 /* 99*/ 0,
2226284134d9SBarry Smith                                         0,
2227284134d9SBarry Smith                                         0,
2228ba337c44SJed Brown                                         MatConjugate_SeqDense,
2229f73d5cc4SBarry Smith                                         0,
2230ba337c44SJed Brown                                 /*104*/ 0,
2231ba337c44SJed Brown                                         MatRealPart_SeqDense,
2232ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2233985db425SBarry Smith                                         0,
2234985db425SBarry Smith                                         0,
22358208b9aeSStefano Zampini                                 /*109*/ 0,
2236985db425SBarry Smith                                         0,
22378d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2238aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
22393b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2240aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2241aabbc4fbSShri Abhyankar                                         0,
2242aabbc4fbSShri Abhyankar                                         0,
2243aabbc4fbSShri Abhyankar                                         0,
2244aabbc4fbSShri Abhyankar                                         0,
2245aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2246aabbc4fbSShri Abhyankar                                         0,
2247aabbc4fbSShri Abhyankar                                         0,
22480716a85fSBarry Smith                                         0,
22490716a85fSBarry Smith                                         0,
22500716a85fSBarry Smith                                 /*124*/ 0,
22515df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
22525df89d91SHong Zhang                                         0,
22535df89d91SHong Zhang                                         0,
22545df89d91SHong Zhang                                         0,
22555df89d91SHong Zhang                                 /*129*/ 0,
225675648e8dSHong Zhang                                         MatTransposeMatMult_SeqDense_SeqDense,
225775648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqDense_SeqDense,
225875648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
22593964eb88SJed Brown                                         0,
22603964eb88SJed Brown                                 /*134*/ 0,
22613964eb88SJed Brown                                         0,
22623964eb88SJed Brown                                         0,
22633964eb88SJed Brown                                         0,
22643964eb88SJed Brown                                         0,
22653964eb88SJed Brown                                 /*139*/ 0,
2266f9426fe0SMark Adams                                         0,
22673964eb88SJed Brown                                         0
2268985db425SBarry Smith };
226990ace30eSBarry Smith 
22704b828684SBarry Smith /*@C
2271fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2272d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2273d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2274289bc588SBarry Smith 
2275db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2276db81eaa0SLois Curfman McInnes 
227720563c6bSBarry Smith    Input Parameters:
2278db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
22790c775827SLois Curfman McInnes .  m - number of rows
228018f449edSLois Curfman McInnes .  n - number of columns
22810298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2282dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
228320563c6bSBarry Smith 
228420563c6bSBarry Smith    Output Parameter:
228544cd7ae7SLois Curfman McInnes .  A - the matrix
228620563c6bSBarry Smith 
2287b259b22eSLois Curfman McInnes    Notes:
228818f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
228918f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
22900298fd71SBarry Smith    set data=NULL.
229118f449edSLois Curfman McInnes 
2292027ccd11SLois Curfman McInnes    Level: intermediate
2293027ccd11SLois Curfman McInnes 
2294dbd7a890SLois Curfman McInnes .keywords: dense, matrix, LAPACK, BLAS
2295d65003e9SLois Curfman McInnes 
229669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
229720563c6bSBarry Smith @*/
22987087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2299289bc588SBarry Smith {
2300dfbe8321SBarry Smith   PetscErrorCode ierr;
23013b2fbd54SBarry Smith 
23023a40ed3dSBarry Smith   PetscFunctionBegin;
2303f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2304f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2305273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2306273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2307273d9f13SBarry Smith   PetscFunctionReturn(0);
2308273d9f13SBarry Smith }
2309273d9f13SBarry Smith 
2310273d9f13SBarry Smith /*@C
2311273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2312273d9f13SBarry Smith 
2313273d9f13SBarry Smith    Collective on MPI_Comm
2314273d9f13SBarry Smith 
2315273d9f13SBarry Smith    Input Parameters:
23161c4f3114SJed Brown +  B - the matrix
23170298fd71SBarry Smith -  data - the array (or NULL)
2318273d9f13SBarry Smith 
2319273d9f13SBarry Smith    Notes:
2320273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2321273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2322284134d9SBarry Smith    need not call this routine.
2323273d9f13SBarry Smith 
2324273d9f13SBarry Smith    Level: intermediate
2325273d9f13SBarry Smith 
2326273d9f13SBarry Smith .keywords: dense, matrix, LAPACK, BLAS
2327273d9f13SBarry Smith 
232869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA()
2329867c911aSBarry Smith 
2330273d9f13SBarry Smith @*/
23317087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2332273d9f13SBarry Smith {
23334ac538c5SBarry Smith   PetscErrorCode ierr;
2334a23d5eceSKris Buschelman 
2335a23d5eceSKris Buschelman   PetscFunctionBegin;
23364ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2337a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2338a23d5eceSKris Buschelman }
2339a23d5eceSKris Buschelman 
23407087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2341a23d5eceSKris Buschelman {
2342273d9f13SBarry Smith   Mat_SeqDense   *b;
2343dfbe8321SBarry Smith   PetscErrorCode ierr;
2344273d9f13SBarry Smith 
2345273d9f13SBarry Smith   PetscFunctionBegin;
2346273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2347a868139aSShri Abhyankar 
234834ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
234934ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
235034ef9618SShri Abhyankar 
2351273d9f13SBarry Smith   b       = (Mat_SeqDense*)B->data;
235286d161a7SShri Abhyankar   b->Mmax = B->rmap->n;
235386d161a7SShri Abhyankar   b->Nmax = B->cmap->n;
235486d161a7SShri Abhyankar   if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n;
235586d161a7SShri Abhyankar 
2356220afb94SBarry Smith   ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr);
23579e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
23589e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2359e92229d0SSatish Balay     ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr);
23603bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
23612205254eSKarl Rupp 
23629e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2363273d9f13SBarry Smith   } else { /* user-allocated storage */
23649e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2365273d9f13SBarry Smith     b->v          = data;
2366273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2367273d9f13SBarry Smith   }
23680450473dSBarry Smith   B->assembled = PETSC_TRUE;
2369273d9f13SBarry Smith   PetscFunctionReturn(0);
2370273d9f13SBarry Smith }
2371273d9f13SBarry Smith 
237265b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2373cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
23748baccfbdSHong Zhang {
2375d77f618aSHong Zhang   Mat            mat_elemental;
2376d77f618aSHong Zhang   PetscErrorCode ierr;
2377d77f618aSHong Zhang   PetscScalar    *array,*v_colwise;
2378d77f618aSHong Zhang   PetscInt       M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2379d77f618aSHong Zhang 
23808baccfbdSHong Zhang   PetscFunctionBegin;
2381d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
2382d77f618aSHong Zhang   ierr = MatDenseGetArray(A,&array);CHKERRQ(ierr);
2383d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2384d77f618aSHong Zhang   k = 0;
2385d77f618aSHong Zhang   for (j=0; j<N; j++) {
2386d77f618aSHong Zhang     cols[j] = j;
2387d77f618aSHong Zhang     for (i=0; i<M; i++) {
2388d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2389d77f618aSHong Zhang     }
2390d77f618aSHong Zhang   }
2391d77f618aSHong Zhang   for (i=0; i<M; i++) {
2392d77f618aSHong Zhang     rows[i] = i;
2393d77f618aSHong Zhang   }
2394d77f618aSHong Zhang   ierr = MatDenseRestoreArray(A,&array);CHKERRQ(ierr);
2395d77f618aSHong Zhang 
2396d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2397d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2398d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2399d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2400d77f618aSHong Zhang 
2401d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2402d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2403d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2404d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2405d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2406d77f618aSHong Zhang 
2407511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
240828be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2409d77f618aSHong Zhang   } else {
2410d77f618aSHong Zhang     *newmat = mat_elemental;
2411d77f618aSHong Zhang   }
24128baccfbdSHong Zhang   PetscFunctionReturn(0);
24138baccfbdSHong Zhang }
241465b80a83SHong Zhang #endif
24158baccfbdSHong Zhang 
24161b807ce4Svictorle /*@C
24171b807ce4Svictorle   MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array
24181b807ce4Svictorle 
24191b807ce4Svictorle   Input parameter:
24201b807ce4Svictorle + A - the matrix
24211b807ce4Svictorle - lda - the leading dimension
24221b807ce4Svictorle 
24231b807ce4Svictorle   Notes:
2424867c911aSBarry Smith   This routine is to be used in conjunction with MatSeqDenseSetPreallocation();
24251b807ce4Svictorle   it asserts that the preallocation has a leading dimension (the LDA parameter
24261b807ce4Svictorle   of Blas and Lapack fame) larger than M, the first dimension of the matrix.
24271b807ce4Svictorle 
24281b807ce4Svictorle   Level: intermediate
24291b807ce4Svictorle 
24301b807ce4Svictorle .keywords: dense, matrix, LAPACK, BLAS
24311b807ce4Svictorle 
2432284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize()
2433867c911aSBarry Smith 
24341b807ce4Svictorle @*/
24357087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetLDA(Mat B,PetscInt lda)
24361b807ce4Svictorle {
24371b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
243821a2c019SBarry Smith 
24391b807ce4Svictorle   PetscFunctionBegin;
2440e32f2f54SBarry 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);
24411b807ce4Svictorle   b->lda       = lda;
244221a2c019SBarry Smith   b->changelda = PETSC_FALSE;
244321a2c019SBarry Smith   b->Mmax      = PetscMax(b->Mmax,lda);
24441b807ce4Svictorle   PetscFunctionReturn(0);
24451b807ce4Svictorle }
24461b807ce4Svictorle 
24470bad9183SKris Buschelman /*MC
2448fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
24490bad9183SKris Buschelman 
24500bad9183SKris Buschelman    Options Database Keys:
24510bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
24520bad9183SKris Buschelman 
24530bad9183SKris Buschelman   Level: beginner
24540bad9183SKris Buschelman 
245589665df3SBarry Smith .seealso: MatCreateSeqDense()
245689665df3SBarry Smith 
24570bad9183SKris Buschelman M*/
24580bad9183SKris Buschelman 
24598cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqDense(Mat B)
2460273d9f13SBarry Smith {
2461273d9f13SBarry Smith   Mat_SeqDense   *b;
2462dfbe8321SBarry Smith   PetscErrorCode ierr;
24637c334f02SBarry Smith   PetscMPIInt    size;
2464273d9f13SBarry Smith 
2465273d9f13SBarry Smith   PetscFunctionBegin;
2466ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
2467e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
246855659b69SBarry Smith 
2469b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
2470549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
247144cd7ae7SLois Curfman McInnes   B->data = (void*)b;
247218f449edSLois Curfman McInnes 
2473273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
24744e220ebcSLois Curfman McInnes 
2475bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2476bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2477bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
24788baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
24798baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
24808baccfbdSHong Zhang #endif
2481bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
2482bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaij_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2483bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2484bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2485abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaij_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
24863bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaij_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
24873bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
24883bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
248917667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
24903a40ed3dSBarry Smith   PetscFunctionReturn(0);
2491289bc588SBarry Smith }
2492