xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 05709791882f40cd3c2fda7deb045cd929b6899a)
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 
118c178816SStefano Zampini static PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian)
128c178816SStefano Zampini {
138c178816SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
148c178816SStefano Zampini   PetscInt      j, k, n = A->rmap->n;
158c178816SStefano Zampini 
168c178816SStefano Zampini   PetscFunctionBegin;
178c178816SStefano Zampini   if (A->rmap->n != A->cmap->n) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot symmetrize a rectangular matrix");
188c178816SStefano Zampini   if (!hermitian) {
198c178816SStefano Zampini     for (k=0;k<n;k++) {
208c178816SStefano Zampini       for (j=k;j<n;j++) {
218c178816SStefano Zampini         mat->v[j*mat->lda + k] = mat->v[k*mat->lda + j];
228c178816SStefano Zampini       }
238c178816SStefano Zampini     }
248c178816SStefano Zampini   } else {
258c178816SStefano Zampini     for (k=0;k<n;k++) {
268c178816SStefano Zampini       for (j=k;j<n;j++) {
278c178816SStefano Zampini         mat->v[j*mat->lda + k] = PetscConj(mat->v[k*mat->lda + j]);
288c178816SStefano Zampini       }
298c178816SStefano Zampini     }
308c178816SStefano Zampini   }
318c178816SStefano Zampini   PetscFunctionReturn(0);
328c178816SStefano Zampini }
338c178816SStefano Zampini 
34*05709791SSatish Balay PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A)
358c178816SStefano Zampini {
368c178816SStefano Zampini #if defined(PETSC_MISSING_LAPACK_POTRF)
378c178816SStefano Zampini   PetscFunctionBegin;
388c178816SStefano Zampini   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF - Lapack routine is unavailable.");
398c178816SStefano Zampini #else
408c178816SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
418c178816SStefano Zampini   PetscErrorCode ierr;
428c178816SStefano Zampini   PetscBLASInt   info,n;
438c178816SStefano Zampini 
448c178816SStefano Zampini   PetscFunctionBegin;
458c178816SStefano Zampini   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
468c178816SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
478c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
488c178816SStefano Zampini     if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
498c178816SStefano Zampini     if (!mat->fwork) {
508c178816SStefano Zampini       mat->lfwork = n;
518c178816SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
528c178816SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
538c178816SStefano Zampini     }
548c178816SStefano Zampini     PetscStackCallBLAS("LAPACKgetri",LAPACKgetri_(&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
558c178816SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr); /* TODO CHECK FLOPS */
568c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
578c178816SStefano Zampini     if (A->spd) {
588c178816SStefano Zampini       PetscStackCallBLAS("LAPACKpotri",LAPACKpotri_("L",&n,mat->v,&mat->lda,&info));
598c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
608c178816SStefano Zampini #if defined (PETSC_USE_COMPLEX)
618c178816SStefano Zampini     } else if (A->hermitian) {
628c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
638c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
648c178816SStefano Zampini       PetscStackCallBLAS("LAPACKhetri",LAPACKhetri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
658c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
668c178816SStefano Zampini #endif
678c178816SStefano Zampini     } else { /* symmetric case */
688c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
698c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
708c178816SStefano Zampini       PetscStackCallBLAS("LAPACKsytri",LAPACKsytri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
718c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_FALSE);CHKERRQ(ierr);
728c178816SStefano Zampini     }
738c178816SStefano Zampini     if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad Inversion: zero pivot in row %D",(PetscInt)info-1);
748c178816SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr); /* TODO CHECK FLOPS */
758c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
768c178816SStefano Zampini #endif
778c178816SStefano Zampini 
788c178816SStefano Zampini   A->ops->solve             = NULL;
798c178816SStefano Zampini   A->ops->matsolve          = NULL;
808c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
818c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
828c178816SStefano Zampini   A->ops->solveadd          = NULL;
838c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
848c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
858c178816SStefano Zampini   ierr                      = PetscFree(A->solvertype);CHKERRQ(ierr);
868c178816SStefano Zampini   PetscFunctionReturn(0);
878c178816SStefano Zampini }
888c178816SStefano 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;
720bd443b22SStefano Zampini   fact->ops->solve                 = MatSolve_SeqDense;
721bd443b22SStefano Zampini   fact->ops->matsolve              = MatMatSolve_SeqDense;
722bd443b22SStefano Zampini   fact->ops->solvetranspose        = MatSolveTranspose_SeqDense;
723bd443b22SStefano Zampini   fact->ops->solveadd              = MatSolveAdd_SeqDense;
724bd443b22SStefano Zampini   fact->ops->solvetransposeadd     = MatSolveTransposeAdd_SeqDense;
725db4efbfdSBarry Smith   PetscFunctionReturn(0);
726db4efbfdSBarry Smith }
727db4efbfdSBarry Smith 
728e0877f53SBarry Smith static PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
729db4efbfdSBarry Smith {
730db4efbfdSBarry Smith   PetscFunctionBegin;
731b66fe19dSMatthew G Knepley   fact->preallocated           = PETSC_TRUE;
732c3ef05f6SHong Zhang   fact->assembled              = PETSC_TRUE;
733719d5645SBarry Smith   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
734bd443b22SStefano Zampini   fact->ops->solve             = MatSolve_SeqDense;
735bd443b22SStefano Zampini   fact->ops->matsolve          = MatMatSolve_SeqDense;
736bd443b22SStefano Zampini   fact->ops->solvetranspose    = MatSolveTranspose_SeqDense;
737bd443b22SStefano Zampini   fact->ops->solveadd          = MatSolveAdd_SeqDense;
738bd443b22SStefano Zampini   fact->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
739db4efbfdSBarry Smith   PetscFunctionReturn(0);
740db4efbfdSBarry Smith }
741db4efbfdSBarry Smith 
742cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
743db4efbfdSBarry Smith {
744db4efbfdSBarry Smith   PetscErrorCode ierr;
745db4efbfdSBarry Smith 
746db4efbfdSBarry Smith   PetscFunctionBegin;
747ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
748db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
749db4efbfdSBarry Smith   ierr = MatSetType(*fact,((PetscObject)A)->type_name);CHKERRQ(ierr);
750db4efbfdSBarry Smith   if (ftype == MAT_FACTOR_LU) {
751db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
752db4efbfdSBarry Smith   } else {
753db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
754db4efbfdSBarry Smith   }
755d5f3da31SBarry Smith   (*fact)->factortype = ftype;
75600c67f3bSHong Zhang 
75700c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
75800c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
759db4efbfdSBarry Smith   PetscFunctionReturn(0);
760db4efbfdSBarry Smith }
761db4efbfdSBarry Smith 
762289bc588SBarry Smith /* ------------------------------------------------------------------*/
763e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
764289bc588SBarry Smith {
765c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
766d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
767d9ca1df4SBarry Smith   const PetscScalar *b;
768dfbe8321SBarry Smith   PetscErrorCode    ierr;
769d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
770c5df96a5SBarry Smith   PetscBLASInt      o = 1,bm;
771289bc588SBarry Smith 
7723a40ed3dSBarry Smith   PetscFunctionBegin;
773422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
774c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
775289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
77671044d3cSBarry Smith     /* this is a hack fix, should have another version without the second BLASdot */
7772dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
778289bc588SBarry Smith   }
7791ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
780d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
781b965ef7fSBarry Smith   its  = its*lits;
782e32f2f54SBarry 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);
783289bc588SBarry Smith   while (its--) {
784fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
785289bc588SBarry Smith       for (i=0; i<m; i++) {
7868b83055fSJed Brown         PetscStackCallBLAS("BLASdot",xt   = b[i] - BLASdot_(&bm,v+i,&bm,x,&o));
78755a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
788289bc588SBarry Smith       }
789289bc588SBarry Smith     }
790fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
791289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
7928b83055fSJed Brown         PetscStackCallBLAS("BLASdot",xt   = b[i] - BLASdot_(&bm,v+i,&bm,x,&o));
79355a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
794289bc588SBarry Smith       }
795289bc588SBarry Smith     }
796289bc588SBarry Smith   }
797d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
7981ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
7993a40ed3dSBarry Smith   PetscFunctionReturn(0);
800289bc588SBarry Smith }
801289bc588SBarry Smith 
802289bc588SBarry Smith /* -----------------------------------------------------------------*/
803cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
804289bc588SBarry Smith {
805c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
806d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
807d9ca1df4SBarry Smith   PetscScalar       *y;
808dfbe8321SBarry Smith   PetscErrorCode    ierr;
8090805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
810ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
8113a40ed3dSBarry Smith 
8123a40ed3dSBarry Smith   PetscFunctionBegin;
813c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
814c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
815d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
816d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8171ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8188b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
819d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8201ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
821dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
8223a40ed3dSBarry Smith   PetscFunctionReturn(0);
823289bc588SBarry Smith }
824800995b7SMatthew Knepley 
825cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
826289bc588SBarry Smith {
827c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
828d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
829dfbe8321SBarry Smith   PetscErrorCode    ierr;
8300805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
831d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
8323a40ed3dSBarry Smith 
8333a40ed3dSBarry Smith   PetscFunctionBegin;
834c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
835c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
836d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
837d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8381ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8398b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
840d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8411ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
842dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
8433a40ed3dSBarry Smith   PetscFunctionReturn(0);
844289bc588SBarry Smith }
8456ee01492SSatish Balay 
846cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
847289bc588SBarry Smith {
848c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
849d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
850d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
851dfbe8321SBarry Smith   PetscErrorCode    ierr;
8520805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
8533a40ed3dSBarry Smith 
8543a40ed3dSBarry Smith   PetscFunctionBegin;
855c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
856c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
857d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
858600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
859d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8601ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8618b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
862d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8631ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
864dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8653a40ed3dSBarry Smith   PetscFunctionReturn(0);
866289bc588SBarry Smith }
8676ee01492SSatish Balay 
868e0877f53SBarry Smith static PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
869289bc588SBarry Smith {
870c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
871d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
872d9ca1df4SBarry Smith   PetscScalar       *y;
873dfbe8321SBarry Smith   PetscErrorCode    ierr;
8740805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
87587828ca2SBarry Smith   PetscScalar       _DOne=1.0;
8763a40ed3dSBarry Smith 
8773a40ed3dSBarry Smith   PetscFunctionBegin;
878c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
879c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
880d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
881600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
882d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8831ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8848b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
885d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8861ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
887dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8883a40ed3dSBarry Smith   PetscFunctionReturn(0);
889289bc588SBarry Smith }
890289bc588SBarry Smith 
891289bc588SBarry Smith /* -----------------------------------------------------------------*/
892e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
893289bc588SBarry Smith {
894c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
89587828ca2SBarry Smith   PetscScalar    *v;
8966849ba73SBarry Smith   PetscErrorCode ierr;
89713f74950SBarry Smith   PetscInt       i;
89867e560aaSBarry Smith 
8993a40ed3dSBarry Smith   PetscFunctionBegin;
900d0f46423SBarry Smith   *ncols = A->cmap->n;
901289bc588SBarry Smith   if (cols) {
902854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
903d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
904289bc588SBarry Smith   }
905289bc588SBarry Smith   if (vals) {
906854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
907289bc588SBarry Smith     v    = mat->v + row;
908d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
909289bc588SBarry Smith   }
9103a40ed3dSBarry Smith   PetscFunctionReturn(0);
911289bc588SBarry Smith }
9126ee01492SSatish Balay 
913e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
914289bc588SBarry Smith {
915dfbe8321SBarry Smith   PetscErrorCode ierr;
9166e111a19SKarl Rupp 
917606d414cSSatish Balay   PetscFunctionBegin;
918606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
919606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
9203a40ed3dSBarry Smith   PetscFunctionReturn(0);
921289bc588SBarry Smith }
922289bc588SBarry Smith /* ----------------------------------------------------------------*/
923e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
924289bc588SBarry Smith {
925c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
92613f74950SBarry Smith   PetscInt     i,j,idx=0;
927d6dfbf8fSBarry Smith 
9283a40ed3dSBarry Smith   PetscFunctionBegin;
929289bc588SBarry Smith   if (!mat->roworiented) {
930dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
931289bc588SBarry Smith       for (j=0; j<n; j++) {
932cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
9332515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
934e32f2f54SBarry 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);
93558804f6dSBarry Smith #endif
936289bc588SBarry Smith         for (i=0; i<m; i++) {
937cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
9382515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
939e32f2f54SBarry 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);
94058804f6dSBarry Smith #endif
941cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
942289bc588SBarry Smith         }
943289bc588SBarry Smith       }
9443a40ed3dSBarry Smith     } else {
945289bc588SBarry Smith       for (j=0; j<n; j++) {
946cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
9472515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
948e32f2f54SBarry 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);
94958804f6dSBarry Smith #endif
950289bc588SBarry Smith         for (i=0; i<m; i++) {
951cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
9522515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
953e32f2f54SBarry 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);
95458804f6dSBarry Smith #endif
955cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
956289bc588SBarry Smith         }
957289bc588SBarry Smith       }
958289bc588SBarry Smith     }
9593a40ed3dSBarry Smith   } else {
960dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
961e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
962cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
9632515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
964e32f2f54SBarry 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);
96558804f6dSBarry Smith #endif
966e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
967cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
9682515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
969e32f2f54SBarry 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);
97058804f6dSBarry Smith #endif
971cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
972e8d4e0b9SBarry Smith         }
973e8d4e0b9SBarry Smith       }
9743a40ed3dSBarry Smith     } else {
975289bc588SBarry Smith       for (i=0; i<m; i++) {
976cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
9772515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
978e32f2f54SBarry 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);
97958804f6dSBarry Smith #endif
980289bc588SBarry Smith         for (j=0; j<n; j++) {
981cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
9822515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
983e32f2f54SBarry 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);
98458804f6dSBarry Smith #endif
985cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
986289bc588SBarry Smith         }
987289bc588SBarry Smith       }
988289bc588SBarry Smith     }
989e8d4e0b9SBarry Smith   }
9903a40ed3dSBarry Smith   PetscFunctionReturn(0);
991289bc588SBarry Smith }
992e8d4e0b9SBarry Smith 
993e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
994ae80bb75SLois Curfman McInnes {
995ae80bb75SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
99613f74950SBarry Smith   PetscInt     i,j;
997ae80bb75SLois Curfman McInnes 
9983a40ed3dSBarry Smith   PetscFunctionBegin;
999ae80bb75SLois Curfman McInnes   /* row-oriented output */
1000ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
100197e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1002e32f2f54SBarry 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);
1003ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
10046f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1005e32f2f54SBarry 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);
100697e567efSBarry Smith       *v++ = mat->v[indexn[j]*mat->lda + indexm[i]];
1007ae80bb75SLois Curfman McInnes     }
1008ae80bb75SLois Curfman McInnes   }
10093a40ed3dSBarry Smith   PetscFunctionReturn(0);
1010ae80bb75SLois Curfman McInnes }
1011ae80bb75SLois Curfman McInnes 
1012289bc588SBarry Smith /* -----------------------------------------------------------------*/
1013289bc588SBarry Smith 
1014e0877f53SBarry Smith static PetscErrorCode MatLoad_SeqDense(Mat newmat,PetscViewer viewer)
1015aabbc4fbSShri Abhyankar {
1016aabbc4fbSShri Abhyankar   Mat_SeqDense   *a;
1017aabbc4fbSShri Abhyankar   PetscErrorCode ierr;
1018aabbc4fbSShri Abhyankar   PetscInt       *scols,i,j,nz,header[4];
1019aabbc4fbSShri Abhyankar   int            fd;
1020aabbc4fbSShri Abhyankar   PetscMPIInt    size;
1021aabbc4fbSShri Abhyankar   PetscInt       *rowlengths = 0,M,N,*cols,grows,gcols;
1022aabbc4fbSShri Abhyankar   PetscScalar    *vals,*svals,*v,*w;
1023ce94432eSBarry Smith   MPI_Comm       comm;
1024aabbc4fbSShri Abhyankar 
1025aabbc4fbSShri Abhyankar   PetscFunctionBegin;
1026c98fd787SBarry Smith   /* force binary viewer to load .info file if it has not yet done so */
1027c98fd787SBarry Smith   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1028ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
1029aabbc4fbSShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1030aabbc4fbSShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"view must have one processor");
1031aabbc4fbSShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
1032aabbc4fbSShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
1033aabbc4fbSShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not matrix object");
1034aabbc4fbSShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
1035aabbc4fbSShri Abhyankar 
1036aabbc4fbSShri Abhyankar   /* set global size if not set already*/
1037aabbc4fbSShri Abhyankar   if (newmat->rmap->n < 0 && newmat->rmap->N < 0 && newmat->cmap->n < 0 && newmat->cmap->N < 0) {
1038aabbc4fbSShri Abhyankar     ierr = MatSetSizes(newmat,M,N,M,N);CHKERRQ(ierr);
1039aabbc4fbSShri Abhyankar   } else {
1040aabbc4fbSShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
1041aabbc4fbSShri Abhyankar     ierr = MatGetSize(newmat,&grows,&gcols);CHKERRQ(ierr);
1042aabbc4fbSShri 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);
1043aabbc4fbSShri Abhyankar   }
1044e6324fbbSBarry Smith   a = (Mat_SeqDense*)newmat->data;
1045e6324fbbSBarry Smith   if (!a->user_alloc) {
10460298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1047e6324fbbSBarry Smith   }
1048aabbc4fbSShri Abhyankar 
1049aabbc4fbSShri Abhyankar   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense */
1050aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
1051aabbc4fbSShri Abhyankar     v = a->v;
1052aabbc4fbSShri Abhyankar     /* Allocate some temp space to read in the values and then flip them
1053aabbc4fbSShri Abhyankar        from row major to column major */
1054854ce69bSBarry Smith     ierr = PetscMalloc1(M*N > 0 ? M*N : 1,&w);CHKERRQ(ierr);
1055aabbc4fbSShri Abhyankar     /* read in nonzero values */
1056aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,w,M*N,PETSC_SCALAR);CHKERRQ(ierr);
1057aabbc4fbSShri Abhyankar     /* now flip the values and store them in the matrix*/
1058aabbc4fbSShri Abhyankar     for (j=0; j<N; j++) {
1059aabbc4fbSShri Abhyankar       for (i=0; i<M; i++) {
1060aabbc4fbSShri Abhyankar         *v++ =w[i*N+j];
1061aabbc4fbSShri Abhyankar       }
1062aabbc4fbSShri Abhyankar     }
1063aabbc4fbSShri Abhyankar     ierr = PetscFree(w);CHKERRQ(ierr);
1064aabbc4fbSShri Abhyankar   } else {
1065aabbc4fbSShri Abhyankar     /* read row lengths */
1066854ce69bSBarry Smith     ierr = PetscMalloc1(M+1,&rowlengths);CHKERRQ(ierr);
1067aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
1068aabbc4fbSShri Abhyankar 
1069aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
1070aabbc4fbSShri Abhyankar     v = a->v;
1071aabbc4fbSShri Abhyankar 
1072aabbc4fbSShri Abhyankar     /* read column indices and nonzeros */
1073854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&scols);CHKERRQ(ierr);
1074aabbc4fbSShri Abhyankar     cols = scols;
1075aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT);CHKERRQ(ierr);
1076854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&svals);CHKERRQ(ierr);
1077aabbc4fbSShri Abhyankar     vals = svals;
1078aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR);CHKERRQ(ierr);
1079aabbc4fbSShri Abhyankar 
1080aabbc4fbSShri Abhyankar     /* insert into matrix */
1081aabbc4fbSShri Abhyankar     for (i=0; i<M; i++) {
1082aabbc4fbSShri Abhyankar       for (j=0; j<rowlengths[i]; j++) v[i+M*scols[j]] = svals[j];
1083aabbc4fbSShri Abhyankar       svals += rowlengths[i]; scols += rowlengths[i];
1084aabbc4fbSShri Abhyankar     }
1085aabbc4fbSShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1086aabbc4fbSShri Abhyankar     ierr = PetscFree(cols);CHKERRQ(ierr);
1087aabbc4fbSShri Abhyankar     ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1088aabbc4fbSShri Abhyankar   }
1089aabbc4fbSShri Abhyankar   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1090aabbc4fbSShri Abhyankar   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1091aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1092aabbc4fbSShri Abhyankar }
1093aabbc4fbSShri Abhyankar 
10946849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1095289bc588SBarry Smith {
1096932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1097dfbe8321SBarry Smith   PetscErrorCode    ierr;
109813f74950SBarry Smith   PetscInt          i,j;
10992dcb1b2aSMatthew Knepley   const char        *name;
110087828ca2SBarry Smith   PetscScalar       *v;
1101f3ef73ceSBarry Smith   PetscViewerFormat format;
11025f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1103ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
11045f481a85SSatish Balay #endif
1105932b0c3eSLois Curfman McInnes 
11063a40ed3dSBarry Smith   PetscFunctionBegin;
1107b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1108456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
11093a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1110fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1111d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1112d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
111344cd7ae7SLois Curfman McInnes       v    = a->v + i;
111477431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1115d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1116aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1117329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
111857622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1119329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
112057622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
11216831982aSBarry Smith         }
112280cd9d93SLois Curfman McInnes #else
11236831982aSBarry Smith         if (*v) {
112457622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
11256831982aSBarry Smith         }
112680cd9d93SLois Curfman McInnes #endif
11271b807ce4Svictorle         v += a->lda;
112880cd9d93SLois Curfman McInnes       }
1129b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
113080cd9d93SLois Curfman McInnes     }
1131d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
11323a40ed3dSBarry Smith   } else {
1133d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1134aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
113547989497SBarry Smith     /* determine if matrix has all real values */
113647989497SBarry Smith     v = a->v;
1137d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1138ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
113947989497SBarry Smith     }
114047989497SBarry Smith #endif
1141fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
11423a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1143d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1144d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1145fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1146ffac6cdbSBarry Smith     }
1147ffac6cdbSBarry Smith 
1148d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1149932b0c3eSLois Curfman McInnes       v = a->v + i;
1150d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1151aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
115247989497SBarry Smith         if (allreal) {
1153c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
115447989497SBarry Smith         } else {
1155c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
115647989497SBarry Smith         }
1157289bc588SBarry Smith #else
1158c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1159289bc588SBarry Smith #endif
11601b807ce4Svictorle         v += a->lda;
1161289bc588SBarry Smith       }
1162b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1163289bc588SBarry Smith     }
1164fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1165b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1166ffac6cdbSBarry Smith     }
1167d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1168da3a660dSBarry Smith   }
1169b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
11703a40ed3dSBarry Smith   PetscFunctionReturn(0);
1171289bc588SBarry Smith }
1172289bc588SBarry Smith 
11736849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_Binary(Mat A,PetscViewer viewer)
1174932b0c3eSLois Curfman McInnes {
1175932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
11766849ba73SBarry Smith   PetscErrorCode    ierr;
117713f74950SBarry Smith   int               fd;
1178d0f46423SBarry Smith   PetscInt          ict,j,n = A->cmap->n,m = A->rmap->n,i,*col_lens,nz = m*n;
1179f4403165SShri Abhyankar   PetscScalar       *v,*anonz,*vals;
1180f4403165SShri Abhyankar   PetscViewerFormat format;
1181932b0c3eSLois Curfman McInnes 
11823a40ed3dSBarry Smith   PetscFunctionBegin;
1183b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
118490ace30eSBarry Smith 
1185f4403165SShri Abhyankar   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1186f4403165SShri Abhyankar   if (format == PETSC_VIEWER_NATIVE) {
1187f4403165SShri Abhyankar     /* store the matrix as a dense matrix */
1188785e854fSJed Brown     ierr = PetscMalloc1(4,&col_lens);CHKERRQ(ierr);
11892205254eSKarl Rupp 
1190f4403165SShri Abhyankar     col_lens[0] = MAT_FILE_CLASSID;
1191f4403165SShri Abhyankar     col_lens[1] = m;
1192f4403165SShri Abhyankar     col_lens[2] = n;
1193f4403165SShri Abhyankar     col_lens[3] = MATRIX_BINARY_FORMAT_DENSE;
11942205254eSKarl Rupp 
1195f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,col_lens,4,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1196f4403165SShri Abhyankar     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1197f4403165SShri Abhyankar 
1198f4403165SShri Abhyankar     /* write out matrix, by rows */
1199854ce69bSBarry Smith     ierr = PetscMalloc1(m*n+1,&vals);CHKERRQ(ierr);
1200f4403165SShri Abhyankar     v    = a->v;
1201f4403165SShri Abhyankar     for (j=0; j<n; j++) {
1202f4403165SShri Abhyankar       for (i=0; i<m; i++) {
1203f4403165SShri Abhyankar         vals[j + i*n] = *v++;
1204f4403165SShri Abhyankar       }
1205f4403165SShri Abhyankar     }
1206f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,vals,n*m,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1207f4403165SShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1208f4403165SShri Abhyankar   } else {
1209854ce69bSBarry Smith     ierr = PetscMalloc1(4+nz,&col_lens);CHKERRQ(ierr);
12102205254eSKarl Rupp 
12110700a824SBarry Smith     col_lens[0] = MAT_FILE_CLASSID;
1212932b0c3eSLois Curfman McInnes     col_lens[1] = m;
1213932b0c3eSLois Curfman McInnes     col_lens[2] = n;
1214932b0c3eSLois Curfman McInnes     col_lens[3] = nz;
1215932b0c3eSLois Curfman McInnes 
1216932b0c3eSLois Curfman McInnes     /* store lengths of each row and write (including header) to file */
1217932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) col_lens[4+i] = n;
12186f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,4+m,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1219932b0c3eSLois Curfman McInnes 
1220932b0c3eSLois Curfman McInnes     /* Possibly should write in smaller increments, not whole matrix at once? */
1221932b0c3eSLois Curfman McInnes     /* store column indices (zero start index) */
1222932b0c3eSLois Curfman McInnes     ict = 0;
1223932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1224932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) col_lens[ict++] = j;
1225932b0c3eSLois Curfman McInnes     }
12266f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
1227606d414cSSatish Balay     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1228932b0c3eSLois Curfman McInnes 
1229932b0c3eSLois Curfman McInnes     /* store nonzero values */
1230854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&anonz);CHKERRQ(ierr);
1231932b0c3eSLois Curfman McInnes     ict  = 0;
1232932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1233932b0c3eSLois Curfman McInnes       v = a->v + i;
1234932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) {
12351b807ce4Svictorle         anonz[ict++] = *v; v += a->lda;
1236932b0c3eSLois Curfman McInnes       }
1237932b0c3eSLois Curfman McInnes     }
12386f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,anonz,nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1239606d414cSSatish Balay     ierr = PetscFree(anonz);CHKERRQ(ierr);
1240f4403165SShri Abhyankar   }
12413a40ed3dSBarry Smith   PetscFunctionReturn(0);
1242932b0c3eSLois Curfman McInnes }
1243932b0c3eSLois Curfman McInnes 
12449804daf3SBarry Smith #include <petscdraw.h>
1245e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1246f1af5d2fSBarry Smith {
1247f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
1248f1af5d2fSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
12496849ba73SBarry Smith   PetscErrorCode    ierr;
1250383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1251383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
125287828ca2SBarry Smith   PetscScalar       *v = a->v;
1253b0a32e0cSBarry Smith   PetscViewer       viewer;
1254b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1255f3ef73ceSBarry Smith   PetscViewerFormat format;
1256f1af5d2fSBarry Smith 
1257f1af5d2fSBarry Smith   PetscFunctionBegin;
1258f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1259b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1260b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1261f1af5d2fSBarry Smith 
1262f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1263383922c3SLisandro Dalcin 
1264fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1265383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1266f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1267f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1268383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1269f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1270f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1271f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1272329f5518SBarry Smith         if (PetscRealPart(v[j*m+i]) >  0.) {
1273b0a32e0cSBarry Smith           color = PETSC_DRAW_RED;
1274329f5518SBarry Smith         } else if (PetscRealPart(v[j*m+i]) <  0.) {
1275b0a32e0cSBarry Smith           color = PETSC_DRAW_BLUE;
1276f1af5d2fSBarry Smith         } else {
1277f1af5d2fSBarry Smith           continue;
1278f1af5d2fSBarry Smith         }
1279b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1280f1af5d2fSBarry Smith       }
1281f1af5d2fSBarry Smith     }
1282383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1283f1af5d2fSBarry Smith   } else {
1284f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1285f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1286b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1287b05fc000SLisandro Dalcin     PetscDraw popup;
1288b05fc000SLisandro Dalcin 
1289f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1290f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1291f1af5d2fSBarry Smith     }
1292383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1293b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
129445f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1295383922c3SLisandro Dalcin 
1296383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1297f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1298f1af5d2fSBarry Smith       x_l = j;
1299f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1300f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1301f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1302f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1303b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1304b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1305f1af5d2fSBarry Smith       }
1306f1af5d2fSBarry Smith     }
1307383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1308f1af5d2fSBarry Smith   }
1309f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1310f1af5d2fSBarry Smith }
1311f1af5d2fSBarry Smith 
1312e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1313f1af5d2fSBarry Smith {
1314b0a32e0cSBarry Smith   PetscDraw      draw;
1315ace3abfcSBarry Smith   PetscBool      isnull;
1316329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1317dfbe8321SBarry Smith   PetscErrorCode ierr;
1318f1af5d2fSBarry Smith 
1319f1af5d2fSBarry Smith   PetscFunctionBegin;
1320b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1321b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1322abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1323f1af5d2fSBarry Smith 
1324d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1325f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1326b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1327832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1328b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
13290298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1330832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1331f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1332f1af5d2fSBarry Smith }
1333f1af5d2fSBarry Smith 
1334dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1335932b0c3eSLois Curfman McInnes {
1336dfbe8321SBarry Smith   PetscErrorCode ierr;
1337ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1338932b0c3eSLois Curfman McInnes 
13393a40ed3dSBarry Smith   PetscFunctionBegin;
1340251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1341251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1342251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
13430f5bd95cSBarry Smith 
1344c45a1595SBarry Smith   if (iascii) {
1345c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
13460f5bd95cSBarry Smith   } else if (isbinary) {
13473a40ed3dSBarry Smith     ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr);
1348f1af5d2fSBarry Smith   } else if (isdraw) {
1349f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1350932b0c3eSLois Curfman McInnes   }
13513a40ed3dSBarry Smith   PetscFunctionReturn(0);
1352932b0c3eSLois Curfman McInnes }
1353289bc588SBarry Smith 
1354e0877f53SBarry Smith static PetscErrorCode MatDestroy_SeqDense(Mat mat)
1355289bc588SBarry Smith {
1356ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1357dfbe8321SBarry Smith   PetscErrorCode ierr;
135890f02eecSBarry Smith 
13593a40ed3dSBarry Smith   PetscFunctionBegin;
1360aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1361d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1362a5a9c739SBarry Smith #endif
136305b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1364a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1365abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
13666857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1367bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1368dbd8c25aSHong Zhang 
1369dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
1370bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
1371bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
13728baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
13738baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
13748baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
13758baccfbdSHong Zhang #endif
1376bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
1377bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1378bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1379bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1380abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatPtAP_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
13813bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
13823bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
13833bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
13843a40ed3dSBarry Smith   PetscFunctionReturn(0);
1385289bc588SBarry Smith }
1386289bc588SBarry Smith 
1387e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1388289bc588SBarry Smith {
1389c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
13906849ba73SBarry Smith   PetscErrorCode ierr;
139113f74950SBarry Smith   PetscInt       k,j,m,n,M;
139287828ca2SBarry Smith   PetscScalar    *v,tmp;
139348b35521SBarry Smith 
13943a40ed3dSBarry Smith   PetscFunctionBegin;
1395d0f46423SBarry Smith   v = mat->v; m = A->rmap->n; M = mat->lda; n = A->cmap->n;
1396cf37664fSBarry Smith   if (reuse == MAT_INPLACE_MATRIX) { /* in place transpose */
1397e7e72b3dSBarry Smith     if (m != n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can not transpose non-square matrix in place");
1398e7e72b3dSBarry Smith     else {
1399d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1400289bc588SBarry Smith         for (k=0; k<j; k++) {
14011b807ce4Svictorle           tmp        = v[j + k*M];
14021b807ce4Svictorle           v[j + k*M] = v[k + j*M];
14031b807ce4Svictorle           v[k + j*M] = tmp;
1404289bc588SBarry Smith         }
1405289bc588SBarry Smith       }
1406d64ed03dSBarry Smith     }
14073a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1408d3e5ee88SLois Curfman McInnes     Mat          tmat;
1409ec8511deSBarry Smith     Mat_SeqDense *tmatd;
141087828ca2SBarry Smith     PetscScalar  *v2;
1411af36a384SStefano Zampini     PetscInt     M2;
1412ea709b57SSatish Balay 
1413fc4dec0aSBarry Smith     if (reuse == MAT_INITIAL_MATRIX) {
1414ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1415d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
14167adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
14170298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1418fc4dec0aSBarry Smith     } else {
1419fc4dec0aSBarry Smith       tmat = *matout;
1420fc4dec0aSBarry Smith     }
1421ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1422af36a384SStefano Zampini     v = mat->v; v2 = tmatd->v; M2 = tmatd->lda;
1423d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1424af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1425d3e5ee88SLois Curfman McInnes     }
14266d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14276d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1428d3e5ee88SLois Curfman McInnes     *matout = tmat;
142948b35521SBarry Smith   }
14303a40ed3dSBarry Smith   PetscFunctionReturn(0);
1431289bc588SBarry Smith }
1432289bc588SBarry Smith 
1433e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1434289bc588SBarry Smith {
1435c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat1 = (Mat_SeqDense*)A1->data;
1436c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat2 = (Mat_SeqDense*)A2->data;
143713f74950SBarry Smith   PetscInt     i,j;
1438a2ea699eSBarry Smith   PetscScalar  *v1,*v2;
14399ea5d5aeSSatish Balay 
14403a40ed3dSBarry Smith   PetscFunctionBegin;
1441d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1442d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1443d0f46423SBarry Smith   for (i=0; i<A1->rmap->n; i++) {
14441b807ce4Svictorle     v1 = mat1->v+i; v2 = mat2->v+i;
1445d0f46423SBarry Smith     for (j=0; j<A1->cmap->n; j++) {
14463a40ed3dSBarry Smith       if (*v1 != *v2) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
14471b807ce4Svictorle       v1 += mat1->lda; v2 += mat2->lda;
14481b807ce4Svictorle     }
1449289bc588SBarry Smith   }
145077c4ece6SBarry Smith   *flg = PETSC_TRUE;
14513a40ed3dSBarry Smith   PetscFunctionReturn(0);
1452289bc588SBarry Smith }
1453289bc588SBarry Smith 
1454e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1455289bc588SBarry Smith {
1456c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
1457dfbe8321SBarry Smith   PetscErrorCode ierr;
145813f74950SBarry Smith   PetscInt       i,n,len;
145987828ca2SBarry Smith   PetscScalar    *x,zero = 0.0;
146044cd7ae7SLois Curfman McInnes 
14613a40ed3dSBarry Smith   PetscFunctionBegin;
14622dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
14637a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
14641ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1465d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1466e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
146744cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
14681b807ce4Svictorle     x[i] = mat->v[i*mat->lda + i];
1469289bc588SBarry Smith   }
14701ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
14713a40ed3dSBarry Smith   PetscFunctionReturn(0);
1472289bc588SBarry Smith }
1473289bc588SBarry Smith 
1474e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1475289bc588SBarry Smith {
1476c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1477f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1478f1ceaac6SMatthew G. Knepley   PetscScalar       x,*v;
1479dfbe8321SBarry Smith   PetscErrorCode    ierr;
1480d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
148155659b69SBarry Smith 
14823a40ed3dSBarry Smith   PetscFunctionBegin;
148328988994SBarry Smith   if (ll) {
14847a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1485f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1486e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1487da3a660dSBarry Smith     for (i=0; i<m; i++) {
1488da3a660dSBarry Smith       x = l[i];
1489da3a660dSBarry Smith       v = mat->v + i;
1490b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1491da3a660dSBarry Smith     }
1492f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1493eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1494da3a660dSBarry Smith   }
149528988994SBarry Smith   if (rr) {
14967a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1497f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1498e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1499da3a660dSBarry Smith     for (i=0; i<n; i++) {
1500da3a660dSBarry Smith       x = r[i];
1501b43bac26SStefano Zampini       v = mat->v + i*mat->lda;
15022205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1503da3a660dSBarry Smith     }
1504f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1505eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1506da3a660dSBarry Smith   }
15073a40ed3dSBarry Smith   PetscFunctionReturn(0);
1508289bc588SBarry Smith }
1509289bc588SBarry Smith 
1510e0877f53SBarry Smith static PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1511289bc588SBarry Smith {
1512c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
151387828ca2SBarry Smith   PetscScalar    *v   = mat->v;
1514329f5518SBarry Smith   PetscReal      sum  = 0.0;
1515d0f46423SBarry Smith   PetscInt       lda  =mat->lda,m=A->rmap->n,i,j;
1516efee365bSSatish Balay   PetscErrorCode ierr;
151755659b69SBarry Smith 
15183a40ed3dSBarry Smith   PetscFunctionBegin;
1519289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1520a5ce6ee0Svictorle     if (lda>m) {
1521d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1522a5ce6ee0Svictorle         v = mat->v+j*lda;
1523a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1524a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1525a5ce6ee0Svictorle         }
1526a5ce6ee0Svictorle       }
1527a5ce6ee0Svictorle     } else {
1528570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1529570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1530570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1531570b7f6dSBarry Smith     }
1532570b7f6dSBarry Smith #else
1533d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1534329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1535289bc588SBarry Smith       }
1536a5ce6ee0Svictorle     }
15378f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1538570b7f6dSBarry Smith #endif
1539dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
15403a40ed3dSBarry Smith   } else if (type == NORM_1) {
1541064f8208SBarry Smith     *nrm = 0.0;
1542d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
15431b807ce4Svictorle       v   = mat->v + j*mat->lda;
1544289bc588SBarry Smith       sum = 0.0;
1545d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
154633a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1547289bc588SBarry Smith       }
1548064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1549289bc588SBarry Smith     }
1550eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
15513a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1552064f8208SBarry Smith     *nrm = 0.0;
1553d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1554289bc588SBarry Smith       v   = mat->v + j;
1555289bc588SBarry Smith       sum = 0.0;
1556d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
15571b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1558289bc588SBarry Smith       }
1559064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1560289bc588SBarry Smith     }
1561eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1562e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
15633a40ed3dSBarry Smith   PetscFunctionReturn(0);
1564289bc588SBarry Smith }
1565289bc588SBarry Smith 
1566e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1567289bc588SBarry Smith {
1568c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
156963ba0a88SBarry Smith   PetscErrorCode ierr;
157067e560aaSBarry Smith 
15713a40ed3dSBarry Smith   PetscFunctionBegin;
1572b5a2b587SKris Buschelman   switch (op) {
1573b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
15744e0d8c25SBarry Smith     aij->roworiented = flg;
1575b5a2b587SKris Buschelman     break;
1576512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1577b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
15783971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
15794e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
158013fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1581b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1582b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
15835021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
15845021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
15855021d80fSJed Brown     break;
15865021d80fSJed Brown   case MAT_SPD:
158777e54ba9SKris Buschelman   case MAT_SYMMETRIC:
158877e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
15899a4540c5SBarry Smith   case MAT_HERMITIAN:
15909a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
15915021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
159277e54ba9SKris Buschelman     break;
1593b5a2b587SKris Buschelman   default:
1594e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
15953a40ed3dSBarry Smith   }
15963a40ed3dSBarry Smith   PetscFunctionReturn(0);
1597289bc588SBarry Smith }
1598289bc588SBarry Smith 
1599e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
16006f0a148fSBarry Smith {
1601ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
16026849ba73SBarry Smith   PetscErrorCode ierr;
1603d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
16043a40ed3dSBarry Smith 
16053a40ed3dSBarry Smith   PetscFunctionBegin;
1606a5ce6ee0Svictorle   if (lda>m) {
1607d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1608a5ce6ee0Svictorle       ierr = PetscMemzero(l->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr);
1609a5ce6ee0Svictorle     }
1610a5ce6ee0Svictorle   } else {
1611d0f46423SBarry Smith     ierr = PetscMemzero(l->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
1612a5ce6ee0Svictorle   }
16133a40ed3dSBarry Smith   PetscFunctionReturn(0);
16146f0a148fSBarry Smith }
16156f0a148fSBarry Smith 
1616e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
16176f0a148fSBarry Smith {
161897b48c8fSBarry Smith   PetscErrorCode    ierr;
1619ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1620b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
162197b48c8fSBarry Smith   PetscScalar       *slot,*bb;
162297b48c8fSBarry Smith   const PetscScalar *xx;
162355659b69SBarry Smith 
16243a40ed3dSBarry Smith   PetscFunctionBegin;
1625b9679d65SBarry Smith #if defined(PETSC_USE_DEBUG)
1626b9679d65SBarry Smith   for (i=0; i<N; i++) {
1627b9679d65SBarry Smith     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1628b9679d65SBarry 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);
1629b9679d65SBarry Smith   }
1630b9679d65SBarry Smith #endif
1631b9679d65SBarry Smith 
163297b48c8fSBarry Smith   /* fix right hand side if needed */
163397b48c8fSBarry Smith   if (x && b) {
163497b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
163597b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
16362205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
163797b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
163897b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
163997b48c8fSBarry Smith   }
164097b48c8fSBarry Smith 
16416f0a148fSBarry Smith   for (i=0; i<N; i++) {
16426f0a148fSBarry Smith     slot = l->v + rows[i];
1643b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
16446f0a148fSBarry Smith   }
1645f4df32b1SMatthew Knepley   if (diag != 0.0) {
1646b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
16476f0a148fSBarry Smith     for (i=0; i<N; i++) {
1648b9679d65SBarry Smith       slot  = l->v + (m+1)*rows[i];
1649f4df32b1SMatthew Knepley       *slot = diag;
16506f0a148fSBarry Smith     }
16516f0a148fSBarry Smith   }
16523a40ed3dSBarry Smith   PetscFunctionReturn(0);
16536f0a148fSBarry Smith }
1654557bce09SLois Curfman McInnes 
1655e0877f53SBarry Smith static PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar *array[])
165664e87e97SBarry Smith {
1657c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
16583a40ed3dSBarry Smith 
16593a40ed3dSBarry Smith   PetscFunctionBegin;
1660e32f2f54SBarry 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");
166164e87e97SBarry Smith   *array = mat->v;
16623a40ed3dSBarry Smith   PetscFunctionReturn(0);
166364e87e97SBarry Smith }
16640754003eSLois Curfman McInnes 
1665e0877f53SBarry Smith static PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar *array[])
1666ff14e315SSatish Balay {
16673a40ed3dSBarry Smith   PetscFunctionBegin;
166809b544d4SBarry Smith   *array = 0; /* user cannot accidently use the array later */
16693a40ed3dSBarry Smith   PetscFunctionReturn(0);
1670ff14e315SSatish Balay }
16710754003eSLois Curfman McInnes 
1672dec5eb66SMatthew G Knepley /*@C
16738c778c55SBarry Smith    MatDenseGetArray - gives access to the array where the data for a SeqDense matrix is stored
167473a71a0fSBarry Smith 
167573a71a0fSBarry Smith    Not Collective
167673a71a0fSBarry Smith 
167773a71a0fSBarry Smith    Input Parameter:
1678579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
167973a71a0fSBarry Smith 
168073a71a0fSBarry Smith    Output Parameter:
168173a71a0fSBarry Smith .   array - pointer to the data
168273a71a0fSBarry Smith 
168373a71a0fSBarry Smith    Level: intermediate
168473a71a0fSBarry Smith 
16858c778c55SBarry Smith .seealso: MatDenseRestoreArray()
168673a71a0fSBarry Smith @*/
16878c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
168873a71a0fSBarry Smith {
168973a71a0fSBarry Smith   PetscErrorCode ierr;
169073a71a0fSBarry Smith 
169173a71a0fSBarry Smith   PetscFunctionBegin;
16928c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
169373a71a0fSBarry Smith   PetscFunctionReturn(0);
169473a71a0fSBarry Smith }
169573a71a0fSBarry Smith 
1696dec5eb66SMatthew G Knepley /*@C
1697579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
169873a71a0fSBarry Smith 
169973a71a0fSBarry Smith    Not Collective
170073a71a0fSBarry Smith 
170173a71a0fSBarry Smith    Input Parameters:
1702579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
170373a71a0fSBarry Smith .  array - pointer to the data
170473a71a0fSBarry Smith 
170573a71a0fSBarry Smith    Level: intermediate
170673a71a0fSBarry Smith 
17078c778c55SBarry Smith .seealso: MatDenseGetArray()
170873a71a0fSBarry Smith @*/
17098c778c55SBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
171073a71a0fSBarry Smith {
171173a71a0fSBarry Smith   PetscErrorCode ierr;
171273a71a0fSBarry Smith 
171373a71a0fSBarry Smith   PetscFunctionBegin;
17148c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
171573a71a0fSBarry Smith   PetscFunctionReturn(0);
171673a71a0fSBarry Smith }
171773a71a0fSBarry Smith 
17187dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
17190754003eSLois Curfman McInnes {
1720c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
17216849ba73SBarry Smith   PetscErrorCode ierr;
17225d0c19d7SBarry Smith   PetscInt       i,j,nrows,ncols;
17235d0c19d7SBarry Smith   const PetscInt *irow,*icol;
172487828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
17250754003eSLois Curfman McInnes   Mat            newmat;
17260754003eSLois Curfman McInnes 
17273a40ed3dSBarry Smith   PetscFunctionBegin;
172878b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
172978b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1730e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1731e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
17320754003eSLois Curfman McInnes 
1733182d2002SSatish Balay   /* Check submatrixcall */
1734182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
173513f74950SBarry Smith     PetscInt n_cols,n_rows;
1736182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
173721a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
1738f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
1739c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
174021a2c019SBarry Smith     }
1741182d2002SSatish Balay     newmat = *B;
1742182d2002SSatish Balay   } else {
17430754003eSLois Curfman McInnes     /* Create and fill new matrix */
1744ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
1745f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
17467adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
17470298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1748182d2002SSatish Balay   }
1749182d2002SSatish Balay 
1750182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1751182d2002SSatish Balay   bv = ((Mat_SeqDense*)newmat->data)->v;
1752182d2002SSatish Balay 
1753182d2002SSatish Balay   for (i=0; i<ncols; i++) {
17546de62eeeSBarry Smith     av = v + mat->lda*icol[i];
17552205254eSKarl Rupp     for (j=0; j<nrows; j++) *bv++ = av[irow[j]];
17560754003eSLois Curfman McInnes   }
1757182d2002SSatish Balay 
1758182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
17596d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17606d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
17610754003eSLois Curfman McInnes 
17620754003eSLois Curfman McInnes   /* Free work space */
176378b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
176478b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1765182d2002SSatish Balay   *B   = newmat;
17663a40ed3dSBarry Smith   PetscFunctionReturn(0);
17670754003eSLois Curfman McInnes }
17680754003eSLois Curfman McInnes 
17697dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1770905e6a2fSBarry Smith {
17716849ba73SBarry Smith   PetscErrorCode ierr;
177213f74950SBarry Smith   PetscInt       i;
1773905e6a2fSBarry Smith 
17743a40ed3dSBarry Smith   PetscFunctionBegin;
1775905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1776df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
1777905e6a2fSBarry Smith   }
1778905e6a2fSBarry Smith 
1779905e6a2fSBarry Smith   for (i=0; i<n; i++) {
17807dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1781905e6a2fSBarry Smith   }
17823a40ed3dSBarry Smith   PetscFunctionReturn(0);
1783905e6a2fSBarry Smith }
1784905e6a2fSBarry Smith 
1785e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
1786c0aa2d19SHong Zhang {
1787c0aa2d19SHong Zhang   PetscFunctionBegin;
1788c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1789c0aa2d19SHong Zhang }
1790c0aa2d19SHong Zhang 
1791e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
1792c0aa2d19SHong Zhang {
1793c0aa2d19SHong Zhang   PetscFunctionBegin;
1794c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1795c0aa2d19SHong Zhang }
1796c0aa2d19SHong Zhang 
1797e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
17984b0e389bSBarry Smith {
17994b0e389bSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
18006849ba73SBarry Smith   PetscErrorCode ierr;
1801d0f46423SBarry Smith   PetscInt       lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
18023a40ed3dSBarry Smith 
18033a40ed3dSBarry Smith   PetscFunctionBegin;
180433f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
180533f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
1806cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
18073a40ed3dSBarry Smith     PetscFunctionReturn(0);
18083a40ed3dSBarry Smith   }
1809e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
1810a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
18110dbb7854Svictorle     for (j=0; j<n; j++) {
1812a5ce6ee0Svictorle       ierr = PetscMemcpy(b->v+j*lda2,a->v+j*lda1,m*sizeof(PetscScalar));CHKERRQ(ierr);
1813a5ce6ee0Svictorle     }
1814a5ce6ee0Svictorle   } else {
1815d0f46423SBarry Smith     ierr = PetscMemcpy(b->v,a->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
1816a5ce6ee0Svictorle   }
1817273d9f13SBarry Smith   PetscFunctionReturn(0);
1818273d9f13SBarry Smith }
1819273d9f13SBarry Smith 
1820e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
1821273d9f13SBarry Smith {
1822dfbe8321SBarry Smith   PetscErrorCode ierr;
1823273d9f13SBarry Smith 
1824273d9f13SBarry Smith   PetscFunctionBegin;
1825273d9f13SBarry Smith   ierr =  MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
18263a40ed3dSBarry Smith   PetscFunctionReturn(0);
18274b0e389bSBarry Smith }
18284b0e389bSBarry Smith 
1829ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
1830ba337c44SJed Brown {
1831ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1832ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1833ba337c44SJed Brown   PetscScalar  *aa = a->v;
1834ba337c44SJed Brown 
1835ba337c44SJed Brown   PetscFunctionBegin;
1836ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
1837ba337c44SJed Brown   PetscFunctionReturn(0);
1838ba337c44SJed Brown }
1839ba337c44SJed Brown 
1840ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
1841ba337c44SJed Brown {
1842ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1843ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1844ba337c44SJed Brown   PetscScalar  *aa = a->v;
1845ba337c44SJed Brown 
1846ba337c44SJed Brown   PetscFunctionBegin;
1847ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
1848ba337c44SJed Brown   PetscFunctionReturn(0);
1849ba337c44SJed Brown }
1850ba337c44SJed Brown 
1851ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
1852ba337c44SJed Brown {
1853ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1854ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1855ba337c44SJed Brown   PetscScalar  *aa = a->v;
1856ba337c44SJed Brown 
1857ba337c44SJed Brown   PetscFunctionBegin;
1858ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1859ba337c44SJed Brown   PetscFunctionReturn(0);
1860ba337c44SJed Brown }
1861284134d9SBarry Smith 
1862a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
1863150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
1864a9fe9ddaSSatish Balay {
1865a9fe9ddaSSatish Balay   PetscErrorCode ierr;
1866a9fe9ddaSSatish Balay 
1867a9fe9ddaSSatish Balay   PetscFunctionBegin;
1868a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
18693ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
1870a9fe9ddaSSatish Balay     ierr = MatMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
18713ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
1872a9fe9ddaSSatish Balay   }
18733ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
1874a9fe9ddaSSatish Balay   ierr = MatMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
18753ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
1876a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1877a9fe9ddaSSatish Balay }
1878a9fe9ddaSSatish Balay 
1879a9fe9ddaSSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
1880a9fe9ddaSSatish Balay {
1881ee16a9a1SHong Zhang   PetscErrorCode ierr;
1882d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
1883ee16a9a1SHong Zhang   Mat            Cmat;
1884a9fe9ddaSSatish Balay 
1885ee16a9a1SHong Zhang   PetscFunctionBegin;
1886e32f2f54SBarry 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);
1887ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
1888ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
1889ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
18900298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
1891d73949e8SHong Zhang 
1892ee16a9a1SHong Zhang   *C = Cmat;
1893ee16a9a1SHong Zhang   PetscFunctionReturn(0);
1894ee16a9a1SHong Zhang }
1895a9fe9ddaSSatish Balay 
1896a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
1897a9fe9ddaSSatish Balay {
1898a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1899a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
1900a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
19010805154bSBarry Smith   PetscBLASInt   m,n,k;
1902a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
1903c5df96a5SBarry Smith   PetscErrorCode ierr;
1904fd4e9aacSBarry Smith   PetscBool      flg;
1905a9fe9ddaSSatish Balay 
1906a9fe9ddaSSatish Balay   PetscFunctionBegin;
1907fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQDENSE,&flg);CHKERRQ(ierr);
1908fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Second matrix must be dense");
1909fd4e9aacSBarry Smith 
1910fd4e9aacSBarry Smith   /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/
1911fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
1912fd4e9aacSBarry Smith   if (flg) {
1913fd4e9aacSBarry Smith     C->ops->matmultnumeric = MatMatMultNumeric_SeqAIJ_SeqDense;
1914fd4e9aacSBarry Smith     ierr = (*C->ops->matmultnumeric)(A,B,C);CHKERRQ(ierr);
1915fd4e9aacSBarry Smith     PetscFunctionReturn(0);
1916fd4e9aacSBarry Smith   }
1917fd4e9aacSBarry Smith 
1918fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&flg);CHKERRQ(ierr);
1919fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"First matrix must be dense");
19208208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
19218208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
1922c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
19235ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
1924a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1925a9fe9ddaSSatish Balay }
1926a9fe9ddaSSatish Balay 
192775648e8dSHong Zhang PetscErrorCode MatTransposeMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
1928a9fe9ddaSSatish Balay {
1929a9fe9ddaSSatish Balay   PetscErrorCode ierr;
1930a9fe9ddaSSatish Balay 
1931a9fe9ddaSSatish Balay   PetscFunctionBegin;
1932a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
19333ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
193475648e8dSHong Zhang     ierr = MatTransposeMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
19353ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
1936a9fe9ddaSSatish Balay   }
19373ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
193875648e8dSHong Zhang   ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
19393ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
1940a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1941a9fe9ddaSSatish Balay }
1942a9fe9ddaSSatish Balay 
194375648e8dSHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
1944a9fe9ddaSSatish Balay {
1945ee16a9a1SHong Zhang   PetscErrorCode ierr;
1946d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
1947ee16a9a1SHong Zhang   Mat            Cmat;
1948a9fe9ddaSSatish Balay 
1949ee16a9a1SHong Zhang   PetscFunctionBegin;
1950e32f2f54SBarry 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);
1951ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
1952ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
1953ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
19540298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
19552205254eSKarl Rupp 
1956ee16a9a1SHong Zhang   Cmat->assembled = PETSC_TRUE;
19572205254eSKarl Rupp 
1958ee16a9a1SHong Zhang   *C = Cmat;
1959ee16a9a1SHong Zhang   PetscFunctionReturn(0);
1960ee16a9a1SHong Zhang }
1961a9fe9ddaSSatish Balay 
196275648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
1963a9fe9ddaSSatish Balay {
1964a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1965a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
1966a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
19670805154bSBarry Smith   PetscBLASInt   m,n,k;
1968a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
1969c5df96a5SBarry Smith   PetscErrorCode ierr;
1970a9fe9ddaSSatish Balay 
1971a9fe9ddaSSatish Balay   PetscFunctionBegin;
19728208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
19738208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
1974c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
19755ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
1976a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1977a9fe9ddaSSatish Balay }
1978985db425SBarry Smith 
1979e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
1980985db425SBarry Smith {
1981985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1982985db425SBarry Smith   PetscErrorCode ierr;
1983d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
1984985db425SBarry Smith   PetscScalar    *x;
1985985db425SBarry Smith   MatScalar      *aa = a->v;
1986985db425SBarry Smith 
1987985db425SBarry Smith   PetscFunctionBegin;
1988e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1989985db425SBarry Smith 
1990985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
1991985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1992985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
1993e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
1994985db425SBarry Smith   for (i=0; i<m; i++) {
1995985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
1996985db425SBarry Smith     for (j=1; j<n; j++) {
1997985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
1998985db425SBarry Smith     }
1999985db425SBarry Smith   }
2000985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2001985db425SBarry Smith   PetscFunctionReturn(0);
2002985db425SBarry Smith }
2003985db425SBarry Smith 
2004e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2005985db425SBarry Smith {
2006985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2007985db425SBarry Smith   PetscErrorCode ierr;
2008d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
2009985db425SBarry Smith   PetscScalar    *x;
2010985db425SBarry Smith   PetscReal      atmp;
2011985db425SBarry Smith   MatScalar      *aa = a->v;
2012985db425SBarry Smith 
2013985db425SBarry Smith   PetscFunctionBegin;
2014e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2015985db425SBarry Smith 
2016985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2017985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2018985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2019e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2020985db425SBarry Smith   for (i=0; i<m; i++) {
20219189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2022985db425SBarry Smith     for (j=1; j<n; j++) {
2023985db425SBarry Smith       atmp = PetscAbsScalar(aa[i+m*j]);
2024985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2025985db425SBarry Smith     }
2026985db425SBarry Smith   }
2027985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2028985db425SBarry Smith   PetscFunctionReturn(0);
2029985db425SBarry Smith }
2030985db425SBarry Smith 
2031e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2032985db425SBarry Smith {
2033985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2034985db425SBarry Smith   PetscErrorCode ierr;
2035d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
2036985db425SBarry Smith   PetscScalar    *x;
2037985db425SBarry Smith   MatScalar      *aa = a->v;
2038985db425SBarry Smith 
2039985db425SBarry Smith   PetscFunctionBegin;
2040e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2041985db425SBarry Smith 
2042985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2043985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2044985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2045e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2046985db425SBarry Smith   for (i=0; i<m; i++) {
2047985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2048985db425SBarry Smith     for (j=1; j<n; j++) {
2049985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
2050985db425SBarry Smith     }
2051985db425SBarry Smith   }
2052985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2053985db425SBarry Smith   PetscFunctionReturn(0);
2054985db425SBarry Smith }
2055985db425SBarry Smith 
2056e0877f53SBarry Smith static PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
20578d0534beSBarry Smith {
20588d0534beSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
20598d0534beSBarry Smith   PetscErrorCode ierr;
20608d0534beSBarry Smith   PetscScalar    *x;
20618d0534beSBarry Smith 
20628d0534beSBarry Smith   PetscFunctionBegin;
2063e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
20648d0534beSBarry Smith 
20658d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2066d0f46423SBarry Smith   ierr = PetscMemcpy(x,a->v+col*a->lda,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
20678d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
20688d0534beSBarry Smith   PetscFunctionReturn(0);
20698d0534beSBarry Smith }
20708d0534beSBarry Smith 
20710716a85fSBarry Smith 
20720716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
20730716a85fSBarry Smith {
20740716a85fSBarry Smith   PetscErrorCode ierr;
20750716a85fSBarry Smith   PetscInt       i,j,m,n;
20760716a85fSBarry Smith   PetscScalar    *a;
20770716a85fSBarry Smith 
20780716a85fSBarry Smith   PetscFunctionBegin;
20790716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
20800716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
20818c778c55SBarry Smith   ierr = MatDenseGetArray(A,&a);CHKERRQ(ierr);
20820716a85fSBarry Smith   if (type == NORM_2) {
20830716a85fSBarry Smith     for (i=0; i<n; i++) {
20840716a85fSBarry Smith       for (j=0; j<m; j++) {
20850716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
20860716a85fSBarry Smith       }
20870716a85fSBarry Smith       a += m;
20880716a85fSBarry Smith     }
20890716a85fSBarry Smith   } else if (type == NORM_1) {
20900716a85fSBarry Smith     for (i=0; i<n; i++) {
20910716a85fSBarry Smith       for (j=0; j<m; j++) {
20920716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
20930716a85fSBarry Smith       }
20940716a85fSBarry Smith       a += m;
20950716a85fSBarry Smith     }
20960716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
20970716a85fSBarry Smith     for (i=0; i<n; i++) {
20980716a85fSBarry Smith       for (j=0; j<m; j++) {
20990716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
21000716a85fSBarry Smith       }
21010716a85fSBarry Smith       a += m;
21020716a85fSBarry Smith     }
2103ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
21048c778c55SBarry Smith   ierr = MatDenseRestoreArray(A,&a);CHKERRQ(ierr);
21050716a85fSBarry Smith   if (type == NORM_2) {
21068f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
21070716a85fSBarry Smith   }
21080716a85fSBarry Smith   PetscFunctionReturn(0);
21090716a85fSBarry Smith }
21100716a85fSBarry Smith 
211173a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
211273a71a0fSBarry Smith {
211373a71a0fSBarry Smith   PetscErrorCode ierr;
211473a71a0fSBarry Smith   PetscScalar    *a;
211573a71a0fSBarry Smith   PetscInt       m,n,i;
211673a71a0fSBarry Smith 
211773a71a0fSBarry Smith   PetscFunctionBegin;
211873a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
21198c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
212073a71a0fSBarry Smith   for (i=0; i<m*n; i++) {
212173a71a0fSBarry Smith     ierr = PetscRandomGetValue(rctx,a+i);CHKERRQ(ierr);
212273a71a0fSBarry Smith   }
21238c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
212473a71a0fSBarry Smith   PetscFunctionReturn(0);
212573a71a0fSBarry Smith }
212673a71a0fSBarry Smith 
21273b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
21283b49f96aSBarry Smith {
21293b49f96aSBarry Smith   PetscFunctionBegin;
21303b49f96aSBarry Smith   *missing = PETSC_FALSE;
21313b49f96aSBarry Smith   PetscFunctionReturn(0);
21323b49f96aSBarry Smith }
213373a71a0fSBarry Smith 
2134abc3b08eSStefano Zampini 
2135289bc588SBarry Smith /* -------------------------------------------------------------------*/
2136a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2137905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2138905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2139905e6a2fSBarry Smith                                         MatMult_SeqDense,
214097304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
21417c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
21427c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2143db4efbfdSBarry Smith                                         0,
2144db4efbfdSBarry Smith                                         0,
2145db4efbfdSBarry Smith                                         0,
2146db4efbfdSBarry Smith                                 /* 10*/ 0,
2147905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2148905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
214941f059aeSBarry Smith                                         MatSOR_SeqDense,
2150ec8511deSBarry Smith                                         MatTranspose_SeqDense,
215197304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2152905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2153905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2154905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2155905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2156c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2157c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2158905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2159905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2160d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2161db4efbfdSBarry Smith                                         0,
2162db4efbfdSBarry Smith                                         0,
2163db4efbfdSBarry Smith                                         0,
2164db4efbfdSBarry Smith                                         0,
21654994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2166273d9f13SBarry Smith                                         0,
2167905e6a2fSBarry Smith                                         0,
216873a71a0fSBarry Smith                                         0,
216973a71a0fSBarry Smith                                         0,
2170d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2171a5ae1ecdSBarry Smith                                         0,
2172a5ae1ecdSBarry Smith                                         0,
2173a5ae1ecdSBarry Smith                                         0,
2174a5ae1ecdSBarry Smith                                         0,
2175d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
21767dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2177a5ae1ecdSBarry Smith                                         0,
21784b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2179a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2180d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2181a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
21827d68702bSBarry Smith                                         MatShift_Basic,
2183a5ae1ecdSBarry Smith                                         0,
21843f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
218573a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2186a5ae1ecdSBarry Smith                                         0,
2187a5ae1ecdSBarry Smith                                         0,
2188a5ae1ecdSBarry Smith                                         0,
2189a5ae1ecdSBarry Smith                                         0,
2190d519adbfSMatthew Knepley                                 /* 54*/ 0,
2191a5ae1ecdSBarry Smith                                         0,
2192a5ae1ecdSBarry Smith                                         0,
2193a5ae1ecdSBarry Smith                                         0,
2194a5ae1ecdSBarry Smith                                         0,
2195d519adbfSMatthew Knepley                                 /* 59*/ 0,
2196e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2197e03a110bSBarry Smith                                         MatView_SeqDense,
2198357abbc8SBarry Smith                                         0,
219997304618SKris Buschelman                                         0,
2200d519adbfSMatthew Knepley                                 /* 64*/ 0,
220197304618SKris Buschelman                                         0,
220297304618SKris Buschelman                                         0,
220397304618SKris Buschelman                                         0,
220497304618SKris Buschelman                                         0,
2205d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
220697304618SKris Buschelman                                         0,
220797304618SKris Buschelman                                         0,
220897304618SKris Buschelman                                         0,
220997304618SKris Buschelman                                         0,
2210d519adbfSMatthew Knepley                                 /* 74*/ 0,
221197304618SKris Buschelman                                         0,
221297304618SKris Buschelman                                         0,
221397304618SKris Buschelman                                         0,
221497304618SKris Buschelman                                         0,
2215d519adbfSMatthew Knepley                                 /* 79*/ 0,
221697304618SKris Buschelman                                         0,
221797304618SKris Buschelman                                         0,
221897304618SKris Buschelman                                         0,
22195bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2220865e5f61SKris Buschelman                                         0,
22211cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2222865e5f61SKris Buschelman                                         0,
2223865e5f61SKris Buschelman                                         0,
2224865e5f61SKris Buschelman                                         0,
2225d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqDense_SeqDense,
2226a9fe9ddaSSatish Balay                                         MatMatMultSymbolic_SeqDense_SeqDense,
2227a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2228abc3b08eSStefano Zampini                                         MatPtAP_SeqDense_SeqDense,
2229abc3b08eSStefano Zampini                                         MatPtAPSymbolic_SeqDense_SeqDense,
2230abc3b08eSStefano Zampini                                 /* 94*/ MatPtAPNumeric_SeqDense_SeqDense,
22315df89d91SHong Zhang                                         0,
22325df89d91SHong Zhang                                         0,
22335df89d91SHong Zhang                                         0,
2234284134d9SBarry Smith                                         0,
2235d519adbfSMatthew Knepley                                 /* 99*/ 0,
2236284134d9SBarry Smith                                         0,
2237284134d9SBarry Smith                                         0,
2238ba337c44SJed Brown                                         MatConjugate_SeqDense,
2239f73d5cc4SBarry Smith                                         0,
2240ba337c44SJed Brown                                 /*104*/ 0,
2241ba337c44SJed Brown                                         MatRealPart_SeqDense,
2242ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2243985db425SBarry Smith                                         0,
2244985db425SBarry Smith                                         0,
22458208b9aeSStefano Zampini                                 /*109*/ 0,
2246985db425SBarry Smith                                         0,
22478d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2248aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
22493b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2250aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2251aabbc4fbSShri Abhyankar                                         0,
2252aabbc4fbSShri Abhyankar                                         0,
2253aabbc4fbSShri Abhyankar                                         0,
2254aabbc4fbSShri Abhyankar                                         0,
2255aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2256aabbc4fbSShri Abhyankar                                         0,
2257aabbc4fbSShri Abhyankar                                         0,
22580716a85fSBarry Smith                                         0,
22590716a85fSBarry Smith                                         0,
22600716a85fSBarry Smith                                 /*124*/ 0,
22615df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
22625df89d91SHong Zhang                                         0,
22635df89d91SHong Zhang                                         0,
22645df89d91SHong Zhang                                         0,
22655df89d91SHong Zhang                                 /*129*/ 0,
226675648e8dSHong Zhang                                         MatTransposeMatMult_SeqDense_SeqDense,
226775648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqDense_SeqDense,
226875648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
22693964eb88SJed Brown                                         0,
22703964eb88SJed Brown                                 /*134*/ 0,
22713964eb88SJed Brown                                         0,
22723964eb88SJed Brown                                         0,
22733964eb88SJed Brown                                         0,
22743964eb88SJed Brown                                         0,
22753964eb88SJed Brown                                 /*139*/ 0,
2276f9426fe0SMark Adams                                         0,
22773964eb88SJed Brown                                         0
2278985db425SBarry Smith };
227990ace30eSBarry Smith 
22804b828684SBarry Smith /*@C
2281fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2282d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2283d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2284289bc588SBarry Smith 
2285db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2286db81eaa0SLois Curfman McInnes 
228720563c6bSBarry Smith    Input Parameters:
2288db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
22890c775827SLois Curfman McInnes .  m - number of rows
229018f449edSLois Curfman McInnes .  n - number of columns
22910298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2292dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
229320563c6bSBarry Smith 
229420563c6bSBarry Smith    Output Parameter:
229544cd7ae7SLois Curfman McInnes .  A - the matrix
229620563c6bSBarry Smith 
2297b259b22eSLois Curfman McInnes    Notes:
229818f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
229918f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
23000298fd71SBarry Smith    set data=NULL.
230118f449edSLois Curfman McInnes 
2302027ccd11SLois Curfman McInnes    Level: intermediate
2303027ccd11SLois Curfman McInnes 
2304dbd7a890SLois Curfman McInnes .keywords: dense, matrix, LAPACK, BLAS
2305d65003e9SLois Curfman McInnes 
230669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
230720563c6bSBarry Smith @*/
23087087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2309289bc588SBarry Smith {
2310dfbe8321SBarry Smith   PetscErrorCode ierr;
23113b2fbd54SBarry Smith 
23123a40ed3dSBarry Smith   PetscFunctionBegin;
2313f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2314f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2315273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2316273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2317273d9f13SBarry Smith   PetscFunctionReturn(0);
2318273d9f13SBarry Smith }
2319273d9f13SBarry Smith 
2320273d9f13SBarry Smith /*@C
2321273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2322273d9f13SBarry Smith 
2323273d9f13SBarry Smith    Collective on MPI_Comm
2324273d9f13SBarry Smith 
2325273d9f13SBarry Smith    Input Parameters:
23261c4f3114SJed Brown +  B - the matrix
23270298fd71SBarry Smith -  data - the array (or NULL)
2328273d9f13SBarry Smith 
2329273d9f13SBarry Smith    Notes:
2330273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2331273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2332284134d9SBarry Smith    need not call this routine.
2333273d9f13SBarry Smith 
2334273d9f13SBarry Smith    Level: intermediate
2335273d9f13SBarry Smith 
2336273d9f13SBarry Smith .keywords: dense, matrix, LAPACK, BLAS
2337273d9f13SBarry Smith 
233869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA()
2339867c911aSBarry Smith 
2340273d9f13SBarry Smith @*/
23417087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2342273d9f13SBarry Smith {
23434ac538c5SBarry Smith   PetscErrorCode ierr;
2344a23d5eceSKris Buschelman 
2345a23d5eceSKris Buschelman   PetscFunctionBegin;
23464ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2347a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2348a23d5eceSKris Buschelman }
2349a23d5eceSKris Buschelman 
23507087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2351a23d5eceSKris Buschelman {
2352273d9f13SBarry Smith   Mat_SeqDense   *b;
2353dfbe8321SBarry Smith   PetscErrorCode ierr;
2354273d9f13SBarry Smith 
2355273d9f13SBarry Smith   PetscFunctionBegin;
2356273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2357a868139aSShri Abhyankar 
235834ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
235934ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
236034ef9618SShri Abhyankar 
2361273d9f13SBarry Smith   b       = (Mat_SeqDense*)B->data;
236286d161a7SShri Abhyankar   b->Mmax = B->rmap->n;
236386d161a7SShri Abhyankar   b->Nmax = B->cmap->n;
236486d161a7SShri Abhyankar   if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n;
236586d161a7SShri Abhyankar 
2366220afb94SBarry Smith   ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr);
23679e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
23689e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2369e92229d0SSatish Balay     ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr);
23703bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
23712205254eSKarl Rupp 
23729e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2373273d9f13SBarry Smith   } else { /* user-allocated storage */
23749e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2375273d9f13SBarry Smith     b->v          = data;
2376273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2377273d9f13SBarry Smith   }
23780450473dSBarry Smith   B->assembled = PETSC_TRUE;
2379273d9f13SBarry Smith   PetscFunctionReturn(0);
2380273d9f13SBarry Smith }
2381273d9f13SBarry Smith 
238265b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2383cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
23848baccfbdSHong Zhang {
2385d77f618aSHong Zhang   Mat            mat_elemental;
2386d77f618aSHong Zhang   PetscErrorCode ierr;
2387d77f618aSHong Zhang   PetscScalar    *array,*v_colwise;
2388d77f618aSHong Zhang   PetscInt       M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2389d77f618aSHong Zhang 
23908baccfbdSHong Zhang   PetscFunctionBegin;
2391d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
2392d77f618aSHong Zhang   ierr = MatDenseGetArray(A,&array);CHKERRQ(ierr);
2393d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2394d77f618aSHong Zhang   k = 0;
2395d77f618aSHong Zhang   for (j=0; j<N; j++) {
2396d77f618aSHong Zhang     cols[j] = j;
2397d77f618aSHong Zhang     for (i=0; i<M; i++) {
2398d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2399d77f618aSHong Zhang     }
2400d77f618aSHong Zhang   }
2401d77f618aSHong Zhang   for (i=0; i<M; i++) {
2402d77f618aSHong Zhang     rows[i] = i;
2403d77f618aSHong Zhang   }
2404d77f618aSHong Zhang   ierr = MatDenseRestoreArray(A,&array);CHKERRQ(ierr);
2405d77f618aSHong Zhang 
2406d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2407d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2408d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2409d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2410d77f618aSHong Zhang 
2411d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2412d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2413d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2414d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2415d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2416d77f618aSHong Zhang 
2417511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
241828be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2419d77f618aSHong Zhang   } else {
2420d77f618aSHong Zhang     *newmat = mat_elemental;
2421d77f618aSHong Zhang   }
24228baccfbdSHong Zhang   PetscFunctionReturn(0);
24238baccfbdSHong Zhang }
242465b80a83SHong Zhang #endif
24258baccfbdSHong Zhang 
24261b807ce4Svictorle /*@C
24271b807ce4Svictorle   MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array
24281b807ce4Svictorle 
24291b807ce4Svictorle   Input parameter:
24301b807ce4Svictorle + A - the matrix
24311b807ce4Svictorle - lda - the leading dimension
24321b807ce4Svictorle 
24331b807ce4Svictorle   Notes:
2434867c911aSBarry Smith   This routine is to be used in conjunction with MatSeqDenseSetPreallocation();
24351b807ce4Svictorle   it asserts that the preallocation has a leading dimension (the LDA parameter
24361b807ce4Svictorle   of Blas and Lapack fame) larger than M, the first dimension of the matrix.
24371b807ce4Svictorle 
24381b807ce4Svictorle   Level: intermediate
24391b807ce4Svictorle 
24401b807ce4Svictorle .keywords: dense, matrix, LAPACK, BLAS
24411b807ce4Svictorle 
2442284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize()
2443867c911aSBarry Smith 
24441b807ce4Svictorle @*/
24457087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetLDA(Mat B,PetscInt lda)
24461b807ce4Svictorle {
24471b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
244821a2c019SBarry Smith 
24491b807ce4Svictorle   PetscFunctionBegin;
2450e32f2f54SBarry 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);
24511b807ce4Svictorle   b->lda       = lda;
245221a2c019SBarry Smith   b->changelda = PETSC_FALSE;
245321a2c019SBarry Smith   b->Mmax      = PetscMax(b->Mmax,lda);
24541b807ce4Svictorle   PetscFunctionReturn(0);
24551b807ce4Svictorle }
24561b807ce4Svictorle 
24570bad9183SKris Buschelman /*MC
2458fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
24590bad9183SKris Buschelman 
24600bad9183SKris Buschelman    Options Database Keys:
24610bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
24620bad9183SKris Buschelman 
24630bad9183SKris Buschelman   Level: beginner
24640bad9183SKris Buschelman 
246589665df3SBarry Smith .seealso: MatCreateSeqDense()
246689665df3SBarry Smith 
24670bad9183SKris Buschelman M*/
24680bad9183SKris Buschelman 
24698cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqDense(Mat B)
2470273d9f13SBarry Smith {
2471273d9f13SBarry Smith   Mat_SeqDense   *b;
2472dfbe8321SBarry Smith   PetscErrorCode ierr;
24737c334f02SBarry Smith   PetscMPIInt    size;
2474273d9f13SBarry Smith 
2475273d9f13SBarry Smith   PetscFunctionBegin;
2476ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
2477e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
247855659b69SBarry Smith 
2479b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
2480549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
248144cd7ae7SLois Curfman McInnes   B->data = (void*)b;
248218f449edSLois Curfman McInnes 
2483273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
24844e220ebcSLois Curfman McInnes 
2485bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2486bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2487bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
24888baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
24898baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
24908baccfbdSHong Zhang #endif
2491bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
2492bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaij_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2493bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2494bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2495abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaij_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
24963bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaij_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
24973bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
24983bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
249917667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
25003a40ed3dSBarry Smith   PetscFunctionReturn(0);
2501289bc588SBarry Smith }
2502