xref: /petsc/src/mat/impls/dense/seq/dense.c (revision d528f656315abb3e9ed20cefcd412dca5570ccae)
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 
3405709791SSatish 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) {
7763bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
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++) {
7863bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&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--) {
7923bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&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);
815d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8161ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8175ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8185ac36cfcSBarry Smith     PetscBLASInt i;
8195ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
8205ac36cfcSBarry Smith   } else {
8218b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
8225ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
8235ac36cfcSBarry Smith   }
824d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8251ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8263a40ed3dSBarry Smith   PetscFunctionReturn(0);
827289bc588SBarry Smith }
828800995b7SMatthew Knepley 
829cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
830289bc588SBarry Smith {
831c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
832d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
833dfbe8321SBarry Smith   PetscErrorCode    ierr;
8340805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
835d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
8363a40ed3dSBarry Smith 
8373a40ed3dSBarry Smith   PetscFunctionBegin;
838c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
839c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
840d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8411ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8425ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8435ac36cfcSBarry Smith     PetscBLASInt i;
8445ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
8455ac36cfcSBarry Smith   } else {
8468b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
8475ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
8485ac36cfcSBarry Smith   }
849d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8501ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8513a40ed3dSBarry Smith   PetscFunctionReturn(0);
852289bc588SBarry Smith }
8536ee01492SSatish Balay 
854cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
855289bc588SBarry Smith {
856c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
857d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
858d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
859dfbe8321SBarry Smith   PetscErrorCode    ierr;
8600805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
8613a40ed3dSBarry Smith 
8623a40ed3dSBarry Smith   PetscFunctionBegin;
863c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
864c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
865d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
866600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
867d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8681ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8698b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
870d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8711ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
872dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8733a40ed3dSBarry Smith   PetscFunctionReturn(0);
874289bc588SBarry Smith }
8756ee01492SSatish Balay 
876e0877f53SBarry Smith static PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
877289bc588SBarry Smith {
878c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
879d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
880d9ca1df4SBarry Smith   PetscScalar       *y;
881dfbe8321SBarry Smith   PetscErrorCode    ierr;
8820805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
88387828ca2SBarry Smith   PetscScalar       _DOne=1.0;
8843a40ed3dSBarry Smith 
8853a40ed3dSBarry Smith   PetscFunctionBegin;
886c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
887c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
888d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
889600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
890d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8911ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8928b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
893d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8941ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
895dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8963a40ed3dSBarry Smith   PetscFunctionReturn(0);
897289bc588SBarry Smith }
898289bc588SBarry Smith 
899289bc588SBarry Smith /* -----------------------------------------------------------------*/
900e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
901289bc588SBarry Smith {
902c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
90387828ca2SBarry Smith   PetscScalar    *v;
9046849ba73SBarry Smith   PetscErrorCode ierr;
90513f74950SBarry Smith   PetscInt       i;
90667e560aaSBarry Smith 
9073a40ed3dSBarry Smith   PetscFunctionBegin;
908d0f46423SBarry Smith   *ncols = A->cmap->n;
909289bc588SBarry Smith   if (cols) {
910854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
911d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
912289bc588SBarry Smith   }
913289bc588SBarry Smith   if (vals) {
914854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
915289bc588SBarry Smith     v    = mat->v + row;
916d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
917289bc588SBarry Smith   }
9183a40ed3dSBarry Smith   PetscFunctionReturn(0);
919289bc588SBarry Smith }
9206ee01492SSatish Balay 
921e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
922289bc588SBarry Smith {
923dfbe8321SBarry Smith   PetscErrorCode ierr;
9246e111a19SKarl Rupp 
925606d414cSSatish Balay   PetscFunctionBegin;
926606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
927606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
9283a40ed3dSBarry Smith   PetscFunctionReturn(0);
929289bc588SBarry Smith }
930289bc588SBarry Smith /* ----------------------------------------------------------------*/
931e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
932289bc588SBarry Smith {
933c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
93413f74950SBarry Smith   PetscInt     i,j,idx=0;
935d6dfbf8fSBarry Smith 
9363a40ed3dSBarry Smith   PetscFunctionBegin;
937289bc588SBarry Smith   if (!mat->roworiented) {
938dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
939289bc588SBarry Smith       for (j=0; j<n; j++) {
940cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
9412515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
942e32f2f54SBarry 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);
94358804f6dSBarry Smith #endif
944289bc588SBarry Smith         for (i=0; i<m; i++) {
945cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
9462515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
947e32f2f54SBarry 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);
94858804f6dSBarry Smith #endif
949cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
950289bc588SBarry Smith         }
951289bc588SBarry Smith       }
9523a40ed3dSBarry Smith     } else {
953289bc588SBarry Smith       for (j=0; j<n; j++) {
954cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
9552515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
956e32f2f54SBarry 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);
95758804f6dSBarry Smith #endif
958289bc588SBarry Smith         for (i=0; i<m; i++) {
959cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
9602515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
961e32f2f54SBarry 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);
96258804f6dSBarry Smith #endif
963cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
964289bc588SBarry Smith         }
965289bc588SBarry Smith       }
966289bc588SBarry Smith     }
9673a40ed3dSBarry Smith   } else {
968dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
969e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
970cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
9712515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
972e32f2f54SBarry 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);
97358804f6dSBarry Smith #endif
974e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
975cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
9762515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
977e32f2f54SBarry 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);
97858804f6dSBarry Smith #endif
979cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
980e8d4e0b9SBarry Smith         }
981e8d4e0b9SBarry Smith       }
9823a40ed3dSBarry Smith     } else {
983289bc588SBarry Smith       for (i=0; i<m; i++) {
984cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
9852515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
986e32f2f54SBarry 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);
98758804f6dSBarry Smith #endif
988289bc588SBarry Smith         for (j=0; j<n; j++) {
989cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
9902515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
991e32f2f54SBarry 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);
99258804f6dSBarry Smith #endif
993cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
994289bc588SBarry Smith         }
995289bc588SBarry Smith       }
996289bc588SBarry Smith     }
997e8d4e0b9SBarry Smith   }
9983a40ed3dSBarry Smith   PetscFunctionReturn(0);
999289bc588SBarry Smith }
1000e8d4e0b9SBarry Smith 
1001e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1002ae80bb75SLois Curfman McInnes {
1003ae80bb75SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
100413f74950SBarry Smith   PetscInt     i,j;
1005ae80bb75SLois Curfman McInnes 
10063a40ed3dSBarry Smith   PetscFunctionBegin;
1007ae80bb75SLois Curfman McInnes   /* row-oriented output */
1008ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
100997e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1010e32f2f54SBarry 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);
1011ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
10126f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1013e32f2f54SBarry 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);
101497e567efSBarry Smith       *v++ = mat->v[indexn[j]*mat->lda + indexm[i]];
1015ae80bb75SLois Curfman McInnes     }
1016ae80bb75SLois Curfman McInnes   }
10173a40ed3dSBarry Smith   PetscFunctionReturn(0);
1018ae80bb75SLois Curfman McInnes }
1019ae80bb75SLois Curfman McInnes 
1020289bc588SBarry Smith /* -----------------------------------------------------------------*/
1021289bc588SBarry Smith 
1022e0877f53SBarry Smith static PetscErrorCode MatLoad_SeqDense(Mat newmat,PetscViewer viewer)
1023aabbc4fbSShri Abhyankar {
1024aabbc4fbSShri Abhyankar   Mat_SeqDense   *a;
1025aabbc4fbSShri Abhyankar   PetscErrorCode ierr;
1026aabbc4fbSShri Abhyankar   PetscInt       *scols,i,j,nz,header[4];
1027aabbc4fbSShri Abhyankar   int            fd;
1028aabbc4fbSShri Abhyankar   PetscMPIInt    size;
1029aabbc4fbSShri Abhyankar   PetscInt       *rowlengths = 0,M,N,*cols,grows,gcols;
1030aabbc4fbSShri Abhyankar   PetscScalar    *vals,*svals,*v,*w;
1031ce94432eSBarry Smith   MPI_Comm       comm;
1032aabbc4fbSShri Abhyankar 
1033aabbc4fbSShri Abhyankar   PetscFunctionBegin;
1034c98fd787SBarry Smith   /* force binary viewer to load .info file if it has not yet done so */
1035c98fd787SBarry Smith   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1036ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
1037aabbc4fbSShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1038aabbc4fbSShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"view must have one processor");
1039aabbc4fbSShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
1040aabbc4fbSShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
1041aabbc4fbSShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not matrix object");
1042aabbc4fbSShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
1043aabbc4fbSShri Abhyankar 
1044aabbc4fbSShri Abhyankar   /* set global size if not set already*/
1045aabbc4fbSShri Abhyankar   if (newmat->rmap->n < 0 && newmat->rmap->N < 0 && newmat->cmap->n < 0 && newmat->cmap->N < 0) {
1046aabbc4fbSShri Abhyankar     ierr = MatSetSizes(newmat,M,N,M,N);CHKERRQ(ierr);
1047aabbc4fbSShri Abhyankar   } else {
1048aabbc4fbSShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
1049aabbc4fbSShri Abhyankar     ierr = MatGetSize(newmat,&grows,&gcols);CHKERRQ(ierr);
1050aabbc4fbSShri 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);
1051aabbc4fbSShri Abhyankar   }
1052e6324fbbSBarry Smith   a = (Mat_SeqDense*)newmat->data;
1053e6324fbbSBarry Smith   if (!a->user_alloc) {
10540298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1055e6324fbbSBarry Smith   }
1056aabbc4fbSShri Abhyankar 
1057aabbc4fbSShri Abhyankar   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense */
1058aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
1059aabbc4fbSShri Abhyankar     v = a->v;
1060aabbc4fbSShri Abhyankar     /* Allocate some temp space to read in the values and then flip them
1061aabbc4fbSShri Abhyankar        from row major to column major */
1062854ce69bSBarry Smith     ierr = PetscMalloc1(M*N > 0 ? M*N : 1,&w);CHKERRQ(ierr);
1063aabbc4fbSShri Abhyankar     /* read in nonzero values */
1064aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,w,M*N,PETSC_SCALAR);CHKERRQ(ierr);
1065aabbc4fbSShri Abhyankar     /* now flip the values and store them in the matrix*/
1066aabbc4fbSShri Abhyankar     for (j=0; j<N; j++) {
1067aabbc4fbSShri Abhyankar       for (i=0; i<M; i++) {
1068aabbc4fbSShri Abhyankar         *v++ =w[i*N+j];
1069aabbc4fbSShri Abhyankar       }
1070aabbc4fbSShri Abhyankar     }
1071aabbc4fbSShri Abhyankar     ierr = PetscFree(w);CHKERRQ(ierr);
1072aabbc4fbSShri Abhyankar   } else {
1073aabbc4fbSShri Abhyankar     /* read row lengths */
1074854ce69bSBarry Smith     ierr = PetscMalloc1(M+1,&rowlengths);CHKERRQ(ierr);
1075aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
1076aabbc4fbSShri Abhyankar 
1077aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
1078aabbc4fbSShri Abhyankar     v = a->v;
1079aabbc4fbSShri Abhyankar 
1080aabbc4fbSShri Abhyankar     /* read column indices and nonzeros */
1081854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&scols);CHKERRQ(ierr);
1082aabbc4fbSShri Abhyankar     cols = scols;
1083aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT);CHKERRQ(ierr);
1084854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&svals);CHKERRQ(ierr);
1085aabbc4fbSShri Abhyankar     vals = svals;
1086aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR);CHKERRQ(ierr);
1087aabbc4fbSShri Abhyankar 
1088aabbc4fbSShri Abhyankar     /* insert into matrix */
1089aabbc4fbSShri Abhyankar     for (i=0; i<M; i++) {
1090aabbc4fbSShri Abhyankar       for (j=0; j<rowlengths[i]; j++) v[i+M*scols[j]] = svals[j];
1091aabbc4fbSShri Abhyankar       svals += rowlengths[i]; scols += rowlengths[i];
1092aabbc4fbSShri Abhyankar     }
1093aabbc4fbSShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1094aabbc4fbSShri Abhyankar     ierr = PetscFree(cols);CHKERRQ(ierr);
1095aabbc4fbSShri Abhyankar     ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1096aabbc4fbSShri Abhyankar   }
1097aabbc4fbSShri Abhyankar   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1098aabbc4fbSShri Abhyankar   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1099aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1100aabbc4fbSShri Abhyankar }
1101aabbc4fbSShri Abhyankar 
11026849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1103289bc588SBarry Smith {
1104932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1105dfbe8321SBarry Smith   PetscErrorCode    ierr;
110613f74950SBarry Smith   PetscInt          i,j;
11072dcb1b2aSMatthew Knepley   const char        *name;
110887828ca2SBarry Smith   PetscScalar       *v;
1109f3ef73ceSBarry Smith   PetscViewerFormat format;
11105f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1111ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
11125f481a85SSatish Balay #endif
1113932b0c3eSLois Curfman McInnes 
11143a40ed3dSBarry Smith   PetscFunctionBegin;
1115b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1116456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
11173a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1118fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1119d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1120d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
112144cd7ae7SLois Curfman McInnes       v    = a->v + i;
112277431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1123d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1124aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1125329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
112657622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1127329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
112857622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
11296831982aSBarry Smith         }
113080cd9d93SLois Curfman McInnes #else
11316831982aSBarry Smith         if (*v) {
113257622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
11336831982aSBarry Smith         }
113480cd9d93SLois Curfman McInnes #endif
11351b807ce4Svictorle         v += a->lda;
113680cd9d93SLois Curfman McInnes       }
1137b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
113880cd9d93SLois Curfman McInnes     }
1139d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
11403a40ed3dSBarry Smith   } else {
1141d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1142aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
114347989497SBarry Smith     /* determine if matrix has all real values */
114447989497SBarry Smith     v = a->v;
1145d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1146ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
114747989497SBarry Smith     }
114847989497SBarry Smith #endif
1149fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
11503a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1151d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1152d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1153fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1154ffac6cdbSBarry Smith     }
1155ffac6cdbSBarry Smith 
1156d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1157932b0c3eSLois Curfman McInnes       v = a->v + i;
1158d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1159aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
116047989497SBarry Smith         if (allreal) {
1161c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
116247989497SBarry Smith         } else {
1163c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
116447989497SBarry Smith         }
1165289bc588SBarry Smith #else
1166c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1167289bc588SBarry Smith #endif
11681b807ce4Svictorle         v += a->lda;
1169289bc588SBarry Smith       }
1170b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1171289bc588SBarry Smith     }
1172fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1173b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1174ffac6cdbSBarry Smith     }
1175d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1176da3a660dSBarry Smith   }
1177b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
11783a40ed3dSBarry Smith   PetscFunctionReturn(0);
1179289bc588SBarry Smith }
1180289bc588SBarry Smith 
11816849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_Binary(Mat A,PetscViewer viewer)
1182932b0c3eSLois Curfman McInnes {
1183932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
11846849ba73SBarry Smith   PetscErrorCode    ierr;
118513f74950SBarry Smith   int               fd;
1186d0f46423SBarry Smith   PetscInt          ict,j,n = A->cmap->n,m = A->rmap->n,i,*col_lens,nz = m*n;
1187f4403165SShri Abhyankar   PetscScalar       *v,*anonz,*vals;
1188f4403165SShri Abhyankar   PetscViewerFormat format;
1189932b0c3eSLois Curfman McInnes 
11903a40ed3dSBarry Smith   PetscFunctionBegin;
1191b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
119290ace30eSBarry Smith 
1193f4403165SShri Abhyankar   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1194f4403165SShri Abhyankar   if (format == PETSC_VIEWER_NATIVE) {
1195f4403165SShri Abhyankar     /* store the matrix as a dense matrix */
1196785e854fSJed Brown     ierr = PetscMalloc1(4,&col_lens);CHKERRQ(ierr);
11972205254eSKarl Rupp 
1198f4403165SShri Abhyankar     col_lens[0] = MAT_FILE_CLASSID;
1199f4403165SShri Abhyankar     col_lens[1] = m;
1200f4403165SShri Abhyankar     col_lens[2] = n;
1201f4403165SShri Abhyankar     col_lens[3] = MATRIX_BINARY_FORMAT_DENSE;
12022205254eSKarl Rupp 
1203f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,col_lens,4,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1204f4403165SShri Abhyankar     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1205f4403165SShri Abhyankar 
1206f4403165SShri Abhyankar     /* write out matrix, by rows */
1207854ce69bSBarry Smith     ierr = PetscMalloc1(m*n+1,&vals);CHKERRQ(ierr);
1208f4403165SShri Abhyankar     v    = a->v;
1209f4403165SShri Abhyankar     for (j=0; j<n; j++) {
1210f4403165SShri Abhyankar       for (i=0; i<m; i++) {
1211f4403165SShri Abhyankar         vals[j + i*n] = *v++;
1212f4403165SShri Abhyankar       }
1213f4403165SShri Abhyankar     }
1214f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,vals,n*m,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1215f4403165SShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1216f4403165SShri Abhyankar   } else {
1217854ce69bSBarry Smith     ierr = PetscMalloc1(4+nz,&col_lens);CHKERRQ(ierr);
12182205254eSKarl Rupp 
12190700a824SBarry Smith     col_lens[0] = MAT_FILE_CLASSID;
1220932b0c3eSLois Curfman McInnes     col_lens[1] = m;
1221932b0c3eSLois Curfman McInnes     col_lens[2] = n;
1222932b0c3eSLois Curfman McInnes     col_lens[3] = nz;
1223932b0c3eSLois Curfman McInnes 
1224932b0c3eSLois Curfman McInnes     /* store lengths of each row and write (including header) to file */
1225932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) col_lens[4+i] = n;
12266f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,4+m,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1227932b0c3eSLois Curfman McInnes 
1228932b0c3eSLois Curfman McInnes     /* Possibly should write in smaller increments, not whole matrix at once? */
1229932b0c3eSLois Curfman McInnes     /* store column indices (zero start index) */
1230932b0c3eSLois Curfman McInnes     ict = 0;
1231932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1232932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) col_lens[ict++] = j;
1233932b0c3eSLois Curfman McInnes     }
12346f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
1235606d414cSSatish Balay     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1236932b0c3eSLois Curfman McInnes 
1237932b0c3eSLois Curfman McInnes     /* store nonzero values */
1238854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&anonz);CHKERRQ(ierr);
1239932b0c3eSLois Curfman McInnes     ict  = 0;
1240932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1241932b0c3eSLois Curfman McInnes       v = a->v + i;
1242932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) {
12431b807ce4Svictorle         anonz[ict++] = *v; v += a->lda;
1244932b0c3eSLois Curfman McInnes       }
1245932b0c3eSLois Curfman McInnes     }
12466f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,anonz,nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1247606d414cSSatish Balay     ierr = PetscFree(anonz);CHKERRQ(ierr);
1248f4403165SShri Abhyankar   }
12493a40ed3dSBarry Smith   PetscFunctionReturn(0);
1250932b0c3eSLois Curfman McInnes }
1251932b0c3eSLois Curfman McInnes 
12529804daf3SBarry Smith #include <petscdraw.h>
1253e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1254f1af5d2fSBarry Smith {
1255f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
1256f1af5d2fSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
12576849ba73SBarry Smith   PetscErrorCode    ierr;
1258383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1259383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
126087828ca2SBarry Smith   PetscScalar       *v = a->v;
1261b0a32e0cSBarry Smith   PetscViewer       viewer;
1262b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1263f3ef73ceSBarry Smith   PetscViewerFormat format;
1264f1af5d2fSBarry Smith 
1265f1af5d2fSBarry Smith   PetscFunctionBegin;
1266f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1267b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1268b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1269f1af5d2fSBarry Smith 
1270f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1271383922c3SLisandro Dalcin 
1272fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1273383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1274f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1275f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1276383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1277f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1278f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1279f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1280329f5518SBarry Smith         if (PetscRealPart(v[j*m+i]) >  0.) {
1281b0a32e0cSBarry Smith           color = PETSC_DRAW_RED;
1282329f5518SBarry Smith         } else if (PetscRealPart(v[j*m+i]) <  0.) {
1283b0a32e0cSBarry Smith           color = PETSC_DRAW_BLUE;
1284f1af5d2fSBarry Smith         } else {
1285f1af5d2fSBarry Smith           continue;
1286f1af5d2fSBarry Smith         }
1287b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1288f1af5d2fSBarry Smith       }
1289f1af5d2fSBarry Smith     }
1290383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1291f1af5d2fSBarry Smith   } else {
1292f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1293f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1294b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1295b05fc000SLisandro Dalcin     PetscDraw popup;
1296b05fc000SLisandro Dalcin 
1297f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1298f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1299f1af5d2fSBarry Smith     }
1300383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1301b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
130245f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1303383922c3SLisandro Dalcin 
1304383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1305f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1306f1af5d2fSBarry Smith       x_l = j;
1307f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1308f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1309f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1310f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1311b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1312b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1313f1af5d2fSBarry Smith       }
1314f1af5d2fSBarry Smith     }
1315383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1316f1af5d2fSBarry Smith   }
1317f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1318f1af5d2fSBarry Smith }
1319f1af5d2fSBarry Smith 
1320e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1321f1af5d2fSBarry Smith {
1322b0a32e0cSBarry Smith   PetscDraw      draw;
1323ace3abfcSBarry Smith   PetscBool      isnull;
1324329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1325dfbe8321SBarry Smith   PetscErrorCode ierr;
1326f1af5d2fSBarry Smith 
1327f1af5d2fSBarry Smith   PetscFunctionBegin;
1328b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1329b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1330abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1331f1af5d2fSBarry Smith 
1332d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1333f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1334b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1335832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1336b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
13370298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1338832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1339f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1340f1af5d2fSBarry Smith }
1341f1af5d2fSBarry Smith 
1342dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1343932b0c3eSLois Curfman McInnes {
1344dfbe8321SBarry Smith   PetscErrorCode ierr;
1345ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1346932b0c3eSLois Curfman McInnes 
13473a40ed3dSBarry Smith   PetscFunctionBegin;
1348251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1349251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1350251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
13510f5bd95cSBarry Smith 
1352c45a1595SBarry Smith   if (iascii) {
1353c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
13540f5bd95cSBarry Smith   } else if (isbinary) {
13553a40ed3dSBarry Smith     ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr);
1356f1af5d2fSBarry Smith   } else if (isdraw) {
1357f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1358932b0c3eSLois Curfman McInnes   }
13593a40ed3dSBarry Smith   PetscFunctionReturn(0);
1360932b0c3eSLois Curfman McInnes }
1361289bc588SBarry Smith 
1362d3042a70SBarry Smith static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar array[])
1363d3042a70SBarry Smith {
1364d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1365d3042a70SBarry Smith 
1366d3042a70SBarry Smith   PetscFunctionBegin;
1367d3042a70SBarry Smith   a->unplacedarray       = a->v;
1368d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1369d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1370d3042a70SBarry Smith   PetscFunctionReturn(0);
1371d3042a70SBarry Smith }
1372d3042a70SBarry Smith 
1373d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1374d3042a70SBarry Smith {
1375d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1376d3042a70SBarry Smith 
1377d3042a70SBarry Smith   PetscFunctionBegin;
1378d3042a70SBarry Smith   a->v             = a->unplacedarray;
1379d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1380d3042a70SBarry Smith   a->unplacedarray = NULL;
1381d3042a70SBarry Smith   PetscFunctionReturn(0);
1382d3042a70SBarry Smith }
1383d3042a70SBarry Smith 
1384e0877f53SBarry Smith static PetscErrorCode MatDestroy_SeqDense(Mat mat)
1385289bc588SBarry Smith {
1386ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1387dfbe8321SBarry Smith   PetscErrorCode ierr;
138890f02eecSBarry Smith 
13893a40ed3dSBarry Smith   PetscFunctionBegin;
1390aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1391d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1392a5a9c739SBarry Smith #endif
139305b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1394a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1395abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
13966857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1397bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1398dbd8c25aSHong Zhang 
1399dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
1400bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
1401d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1402d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
1403bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
14048baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
14058baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
14068baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
14078baccfbdSHong Zhang #endif
1408bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
1409bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1410bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1411bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1412abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatPtAP_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14133bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14143bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14153bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
141686aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
141786aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
14183a40ed3dSBarry Smith   PetscFunctionReturn(0);
1419289bc588SBarry Smith }
1420289bc588SBarry Smith 
1421e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1422289bc588SBarry Smith {
1423c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
14246849ba73SBarry Smith   PetscErrorCode ierr;
142513f74950SBarry Smith   PetscInt       k,j,m,n,M;
142687828ca2SBarry Smith   PetscScalar    *v,tmp;
142748b35521SBarry Smith 
14283a40ed3dSBarry Smith   PetscFunctionBegin;
1429d0f46423SBarry Smith   v = mat->v; m = A->rmap->n; M = mat->lda; n = A->cmap->n;
1430cf37664fSBarry Smith   if (reuse == MAT_INPLACE_MATRIX) { /* in place transpose */
1431e7e72b3dSBarry Smith     if (m != n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can not transpose non-square matrix in place");
1432e7e72b3dSBarry Smith     else {
1433d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1434289bc588SBarry Smith         for (k=0; k<j; k++) {
14351b807ce4Svictorle           tmp        = v[j + k*M];
14361b807ce4Svictorle           v[j + k*M] = v[k + j*M];
14371b807ce4Svictorle           v[k + j*M] = tmp;
1438289bc588SBarry Smith         }
1439289bc588SBarry Smith       }
1440d64ed03dSBarry Smith     }
14413a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1442d3e5ee88SLois Curfman McInnes     Mat          tmat;
1443ec8511deSBarry Smith     Mat_SeqDense *tmatd;
144487828ca2SBarry Smith     PetscScalar  *v2;
1445af36a384SStefano Zampini     PetscInt     M2;
1446ea709b57SSatish Balay 
1447fc4dec0aSBarry Smith     if (reuse == MAT_INITIAL_MATRIX) {
1448ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1449d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
14507adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
14510298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1452fc4dec0aSBarry Smith     } else {
1453fc4dec0aSBarry Smith       tmat = *matout;
1454fc4dec0aSBarry Smith     }
1455ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1456af36a384SStefano Zampini     v = mat->v; v2 = tmatd->v; M2 = tmatd->lda;
1457d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1458af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1459d3e5ee88SLois Curfman McInnes     }
14606d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14616d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1462d3e5ee88SLois Curfman McInnes     *matout = tmat;
146348b35521SBarry Smith   }
14643a40ed3dSBarry Smith   PetscFunctionReturn(0);
1465289bc588SBarry Smith }
1466289bc588SBarry Smith 
1467e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1468289bc588SBarry Smith {
1469c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat1 = (Mat_SeqDense*)A1->data;
1470c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat2 = (Mat_SeqDense*)A2->data;
147113f74950SBarry Smith   PetscInt     i,j;
1472a2ea699eSBarry Smith   PetscScalar  *v1,*v2;
14739ea5d5aeSSatish Balay 
14743a40ed3dSBarry Smith   PetscFunctionBegin;
1475d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1476d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1477d0f46423SBarry Smith   for (i=0; i<A1->rmap->n; i++) {
14781b807ce4Svictorle     v1 = mat1->v+i; v2 = mat2->v+i;
1479d0f46423SBarry Smith     for (j=0; j<A1->cmap->n; j++) {
14803a40ed3dSBarry Smith       if (*v1 != *v2) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
14811b807ce4Svictorle       v1 += mat1->lda; v2 += mat2->lda;
14821b807ce4Svictorle     }
1483289bc588SBarry Smith   }
148477c4ece6SBarry Smith   *flg = PETSC_TRUE;
14853a40ed3dSBarry Smith   PetscFunctionReturn(0);
1486289bc588SBarry Smith }
1487289bc588SBarry Smith 
1488e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1489289bc588SBarry Smith {
1490c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
1491dfbe8321SBarry Smith   PetscErrorCode ierr;
149213f74950SBarry Smith   PetscInt       i,n,len;
149387828ca2SBarry Smith   PetscScalar    *x,zero = 0.0;
149444cd7ae7SLois Curfman McInnes 
14953a40ed3dSBarry Smith   PetscFunctionBegin;
14962dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
14977a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
14981ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1499d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1500e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
150144cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
15021b807ce4Svictorle     x[i] = mat->v[i*mat->lda + i];
1503289bc588SBarry Smith   }
15041ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
15053a40ed3dSBarry Smith   PetscFunctionReturn(0);
1506289bc588SBarry Smith }
1507289bc588SBarry Smith 
1508e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1509289bc588SBarry Smith {
1510c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1511f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1512f1ceaac6SMatthew G. Knepley   PetscScalar       x,*v;
1513dfbe8321SBarry Smith   PetscErrorCode    ierr;
1514d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
151555659b69SBarry Smith 
15163a40ed3dSBarry Smith   PetscFunctionBegin;
151728988994SBarry Smith   if (ll) {
15187a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1519f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1520e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1521da3a660dSBarry Smith     for (i=0; i<m; i++) {
1522da3a660dSBarry Smith       x = l[i];
1523da3a660dSBarry Smith       v = mat->v + i;
1524b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1525da3a660dSBarry Smith     }
1526f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1527eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1528da3a660dSBarry Smith   }
152928988994SBarry Smith   if (rr) {
15307a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1531f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1532e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1533da3a660dSBarry Smith     for (i=0; i<n; i++) {
1534da3a660dSBarry Smith       x = r[i];
1535b43bac26SStefano Zampini       v = mat->v + i*mat->lda;
15362205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1537da3a660dSBarry Smith     }
1538f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1539eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1540da3a660dSBarry Smith   }
15413a40ed3dSBarry Smith   PetscFunctionReturn(0);
1542289bc588SBarry Smith }
1543289bc588SBarry Smith 
1544e0877f53SBarry Smith static PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1545289bc588SBarry Smith {
1546c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
154787828ca2SBarry Smith   PetscScalar    *v   = mat->v;
1548329f5518SBarry Smith   PetscReal      sum  = 0.0;
1549d0f46423SBarry Smith   PetscInt       lda  =mat->lda,m=A->rmap->n,i,j;
1550efee365bSSatish Balay   PetscErrorCode ierr;
155155659b69SBarry Smith 
15523a40ed3dSBarry Smith   PetscFunctionBegin;
1553289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1554a5ce6ee0Svictorle     if (lda>m) {
1555d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1556a5ce6ee0Svictorle         v = mat->v+j*lda;
1557a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1558a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1559a5ce6ee0Svictorle         }
1560a5ce6ee0Svictorle       }
1561a5ce6ee0Svictorle     } else {
1562570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1563570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1564570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1565570b7f6dSBarry Smith     }
1566570b7f6dSBarry Smith #else
1567d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1568329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1569289bc588SBarry Smith       }
1570a5ce6ee0Svictorle     }
15718f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1572570b7f6dSBarry Smith #endif
1573dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
15743a40ed3dSBarry Smith   } else if (type == NORM_1) {
1575064f8208SBarry Smith     *nrm = 0.0;
1576d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
15771b807ce4Svictorle       v   = mat->v + j*mat->lda;
1578289bc588SBarry Smith       sum = 0.0;
1579d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
158033a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1581289bc588SBarry Smith       }
1582064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1583289bc588SBarry Smith     }
1584eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
15853a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1586064f8208SBarry Smith     *nrm = 0.0;
1587d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1588289bc588SBarry Smith       v   = mat->v + j;
1589289bc588SBarry Smith       sum = 0.0;
1590d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
15911b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1592289bc588SBarry Smith       }
1593064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1594289bc588SBarry Smith     }
1595eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1596e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
15973a40ed3dSBarry Smith   PetscFunctionReturn(0);
1598289bc588SBarry Smith }
1599289bc588SBarry Smith 
1600e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1601289bc588SBarry Smith {
1602c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
160363ba0a88SBarry Smith   PetscErrorCode ierr;
160467e560aaSBarry Smith 
16053a40ed3dSBarry Smith   PetscFunctionBegin;
1606b5a2b587SKris Buschelman   switch (op) {
1607b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
16084e0d8c25SBarry Smith     aij->roworiented = flg;
1609b5a2b587SKris Buschelman     break;
1610512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1611b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
16123971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
16134e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
161413fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1615b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1616b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
16170f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
16185021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
16195021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
16205021d80fSJed Brown     break;
16215021d80fSJed Brown   case MAT_SPD:
162277e54ba9SKris Buschelman   case MAT_SYMMETRIC:
162377e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
16249a4540c5SBarry Smith   case MAT_HERMITIAN:
16259a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
16265021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
162777e54ba9SKris Buschelman     break;
1628b5a2b587SKris Buschelman   default:
1629e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
16303a40ed3dSBarry Smith   }
16313a40ed3dSBarry Smith   PetscFunctionReturn(0);
1632289bc588SBarry Smith }
1633289bc588SBarry Smith 
1634e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
16356f0a148fSBarry Smith {
1636ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
16376849ba73SBarry Smith   PetscErrorCode ierr;
1638d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
16393a40ed3dSBarry Smith 
16403a40ed3dSBarry Smith   PetscFunctionBegin;
1641a5ce6ee0Svictorle   if (lda>m) {
1642d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1643a5ce6ee0Svictorle       ierr = PetscMemzero(l->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr);
1644a5ce6ee0Svictorle     }
1645a5ce6ee0Svictorle   } else {
1646d0f46423SBarry Smith     ierr = PetscMemzero(l->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
1647a5ce6ee0Svictorle   }
16483a40ed3dSBarry Smith   PetscFunctionReturn(0);
16496f0a148fSBarry Smith }
16506f0a148fSBarry Smith 
1651e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
16526f0a148fSBarry Smith {
165397b48c8fSBarry Smith   PetscErrorCode    ierr;
1654ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1655b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
165697b48c8fSBarry Smith   PetscScalar       *slot,*bb;
165797b48c8fSBarry Smith   const PetscScalar *xx;
165855659b69SBarry Smith 
16593a40ed3dSBarry Smith   PetscFunctionBegin;
1660b9679d65SBarry Smith #if defined(PETSC_USE_DEBUG)
1661b9679d65SBarry Smith   for (i=0; i<N; i++) {
1662b9679d65SBarry Smith     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1663b9679d65SBarry 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);
1664b9679d65SBarry Smith   }
1665b9679d65SBarry Smith #endif
1666b9679d65SBarry Smith 
166797b48c8fSBarry Smith   /* fix right hand side if needed */
166897b48c8fSBarry Smith   if (x && b) {
166997b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
167097b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
16712205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
167297b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
167397b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
167497b48c8fSBarry Smith   }
167597b48c8fSBarry Smith 
16766f0a148fSBarry Smith   for (i=0; i<N; i++) {
16776f0a148fSBarry Smith     slot = l->v + rows[i];
1678b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
16796f0a148fSBarry Smith   }
1680f4df32b1SMatthew Knepley   if (diag != 0.0) {
1681b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
16826f0a148fSBarry Smith     for (i=0; i<N; i++) {
1683b9679d65SBarry Smith       slot  = l->v + (m+1)*rows[i];
1684f4df32b1SMatthew Knepley       *slot = diag;
16856f0a148fSBarry Smith     }
16866f0a148fSBarry Smith   }
16873a40ed3dSBarry Smith   PetscFunctionReturn(0);
16886f0a148fSBarry Smith }
1689557bce09SLois Curfman McInnes 
1690e0877f53SBarry Smith static PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar *array[])
169164e87e97SBarry Smith {
1692c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
16933a40ed3dSBarry Smith 
16943a40ed3dSBarry Smith   PetscFunctionBegin;
1695e32f2f54SBarry 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");
169664e87e97SBarry Smith   *array = mat->v;
16973a40ed3dSBarry Smith   PetscFunctionReturn(0);
169864e87e97SBarry Smith }
16990754003eSLois Curfman McInnes 
1700e0877f53SBarry Smith static PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar *array[])
1701ff14e315SSatish Balay {
17023a40ed3dSBarry Smith   PetscFunctionBegin;
17033a40ed3dSBarry Smith   PetscFunctionReturn(0);
1704ff14e315SSatish Balay }
17050754003eSLois Curfman McInnes 
1706dec5eb66SMatthew G Knepley /*@C
17078c778c55SBarry Smith    MatDenseGetArray - gives access to the array where the data for a SeqDense matrix is stored
170873a71a0fSBarry Smith 
17098572280aSBarry Smith    Logically Collective on Mat
171073a71a0fSBarry Smith 
171173a71a0fSBarry Smith    Input Parameter:
1712579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
171373a71a0fSBarry Smith 
171473a71a0fSBarry Smith    Output Parameter:
171573a71a0fSBarry Smith .   array - pointer to the data
171673a71a0fSBarry Smith 
171773a71a0fSBarry Smith    Level: intermediate
171873a71a0fSBarry Smith 
17198572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
172073a71a0fSBarry Smith @*/
17218c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
172273a71a0fSBarry Smith {
172373a71a0fSBarry Smith   PetscErrorCode ierr;
172473a71a0fSBarry Smith 
172573a71a0fSBarry Smith   PetscFunctionBegin;
17268c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
172773a71a0fSBarry Smith   PetscFunctionReturn(0);
172873a71a0fSBarry Smith }
172973a71a0fSBarry Smith 
1730dec5eb66SMatthew G Knepley /*@C
1731579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
173273a71a0fSBarry Smith 
17338572280aSBarry Smith    Logically Collective on Mat
17348572280aSBarry Smith 
17358572280aSBarry Smith    Input Parameters:
17368572280aSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
17378572280aSBarry Smith .  array - pointer to the data
17388572280aSBarry Smith 
17398572280aSBarry Smith    Level: intermediate
17408572280aSBarry Smith 
17418572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
17428572280aSBarry Smith @*/
17438572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
17448572280aSBarry Smith {
17458572280aSBarry Smith   PetscErrorCode ierr;
17468572280aSBarry Smith 
17478572280aSBarry Smith   PetscFunctionBegin;
17488572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
17498572280aSBarry Smith   if (array) *array = NULL;
17508572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
17518572280aSBarry Smith   PetscFunctionReturn(0);
17528572280aSBarry Smith }
17538572280aSBarry Smith 
17548572280aSBarry Smith /*@C
17558572280aSBarry Smith    MatDenseGetArrayRead - gives access to the array where the data for a SeqDense matrix is stored
17568572280aSBarry Smith 
17578572280aSBarry Smith    Not Collective
17588572280aSBarry Smith 
17598572280aSBarry Smith    Input Parameter:
17608572280aSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
17618572280aSBarry Smith 
17628572280aSBarry Smith    Output Parameter:
17638572280aSBarry Smith .   array - pointer to the data
17648572280aSBarry Smith 
17658572280aSBarry Smith    Level: intermediate
17668572280aSBarry Smith 
17678572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArray(), MatDenseRestoreArrayRead()
17688572280aSBarry Smith @*/
17698572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
17708572280aSBarry Smith {
17718572280aSBarry Smith   PetscErrorCode ierr;
17728572280aSBarry Smith 
17738572280aSBarry Smith   PetscFunctionBegin;
17748572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
17758572280aSBarry Smith   PetscFunctionReturn(0);
17768572280aSBarry Smith }
17778572280aSBarry Smith 
17788572280aSBarry Smith /*@C
17798572280aSBarry Smith    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
17808572280aSBarry Smith 
178173a71a0fSBarry Smith    Not Collective
178273a71a0fSBarry Smith 
178373a71a0fSBarry Smith    Input Parameters:
1784579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
178573a71a0fSBarry Smith .  array - pointer to the data
178673a71a0fSBarry Smith 
178773a71a0fSBarry Smith    Level: intermediate
178873a71a0fSBarry Smith 
17898572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArray()
179073a71a0fSBarry Smith @*/
17918572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
179273a71a0fSBarry Smith {
179373a71a0fSBarry Smith   PetscErrorCode ierr;
179473a71a0fSBarry Smith 
179573a71a0fSBarry Smith   PetscFunctionBegin;
17968572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
17978572280aSBarry Smith   if (array) *array = NULL;
179873a71a0fSBarry Smith   PetscFunctionReturn(0);
179973a71a0fSBarry Smith }
180073a71a0fSBarry Smith 
18017dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
18020754003eSLois Curfman McInnes {
1803c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
18046849ba73SBarry Smith   PetscErrorCode ierr;
18055d0c19d7SBarry Smith   PetscInt       i,j,nrows,ncols;
18065d0c19d7SBarry Smith   const PetscInt *irow,*icol;
180787828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
18080754003eSLois Curfman McInnes   Mat            newmat;
18090754003eSLois Curfman McInnes 
18103a40ed3dSBarry Smith   PetscFunctionBegin;
181178b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
181278b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1813e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1814e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
18150754003eSLois Curfman McInnes 
1816182d2002SSatish Balay   /* Check submatrixcall */
1817182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
181813f74950SBarry Smith     PetscInt n_cols,n_rows;
1819182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
182021a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
1821f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
1822c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
182321a2c019SBarry Smith     }
1824182d2002SSatish Balay     newmat = *B;
1825182d2002SSatish Balay   } else {
18260754003eSLois Curfman McInnes     /* Create and fill new matrix */
1827ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
1828f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
18297adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
18300298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1831182d2002SSatish Balay   }
1832182d2002SSatish Balay 
1833182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1834182d2002SSatish Balay   bv = ((Mat_SeqDense*)newmat->data)->v;
1835182d2002SSatish Balay 
1836182d2002SSatish Balay   for (i=0; i<ncols; i++) {
18376de62eeeSBarry Smith     av = v + mat->lda*icol[i];
18382205254eSKarl Rupp     for (j=0; j<nrows; j++) *bv++ = av[irow[j]];
18390754003eSLois Curfman McInnes   }
1840182d2002SSatish Balay 
1841182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
18426d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18436d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18440754003eSLois Curfman McInnes 
18450754003eSLois Curfman McInnes   /* Free work space */
184678b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
184778b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1848182d2002SSatish Balay   *B   = newmat;
18493a40ed3dSBarry Smith   PetscFunctionReturn(0);
18500754003eSLois Curfman McInnes }
18510754003eSLois Curfman McInnes 
18527dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1853905e6a2fSBarry Smith {
18546849ba73SBarry Smith   PetscErrorCode ierr;
185513f74950SBarry Smith   PetscInt       i;
1856905e6a2fSBarry Smith 
18573a40ed3dSBarry Smith   PetscFunctionBegin;
1858905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1859df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
1860905e6a2fSBarry Smith   }
1861905e6a2fSBarry Smith 
1862905e6a2fSBarry Smith   for (i=0; i<n; i++) {
18637dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1864905e6a2fSBarry Smith   }
18653a40ed3dSBarry Smith   PetscFunctionReturn(0);
1866905e6a2fSBarry Smith }
1867905e6a2fSBarry Smith 
1868e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
1869c0aa2d19SHong Zhang {
1870c0aa2d19SHong Zhang   PetscFunctionBegin;
1871c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1872c0aa2d19SHong Zhang }
1873c0aa2d19SHong Zhang 
1874e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
1875c0aa2d19SHong Zhang {
1876c0aa2d19SHong Zhang   PetscFunctionBegin;
1877c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1878c0aa2d19SHong Zhang }
1879c0aa2d19SHong Zhang 
1880e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
18814b0e389bSBarry Smith {
18824b0e389bSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
18836849ba73SBarry Smith   PetscErrorCode ierr;
1884d0f46423SBarry Smith   PetscInt       lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
18853a40ed3dSBarry Smith 
18863a40ed3dSBarry Smith   PetscFunctionBegin;
188733f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
188833f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
1889cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
18903a40ed3dSBarry Smith     PetscFunctionReturn(0);
18913a40ed3dSBarry Smith   }
1892e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
1893a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
18940dbb7854Svictorle     for (j=0; j<n; j++) {
1895a5ce6ee0Svictorle       ierr = PetscMemcpy(b->v+j*lda2,a->v+j*lda1,m*sizeof(PetscScalar));CHKERRQ(ierr);
1896a5ce6ee0Svictorle     }
1897a5ce6ee0Svictorle   } else {
1898d0f46423SBarry Smith     ierr = PetscMemcpy(b->v,a->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
1899a5ce6ee0Svictorle   }
1900cdc753b6SBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
1901273d9f13SBarry Smith   PetscFunctionReturn(0);
1902273d9f13SBarry Smith }
1903273d9f13SBarry Smith 
1904e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
1905273d9f13SBarry Smith {
1906dfbe8321SBarry Smith   PetscErrorCode ierr;
1907273d9f13SBarry Smith 
1908273d9f13SBarry Smith   PetscFunctionBegin;
1909273d9f13SBarry Smith   ierr =  MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
19103a40ed3dSBarry Smith   PetscFunctionReturn(0);
19114b0e389bSBarry Smith }
19124b0e389bSBarry Smith 
1913ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
1914ba337c44SJed Brown {
1915ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1916ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1917ba337c44SJed Brown   PetscScalar  *aa = a->v;
1918ba337c44SJed Brown 
1919ba337c44SJed Brown   PetscFunctionBegin;
1920ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
1921ba337c44SJed Brown   PetscFunctionReturn(0);
1922ba337c44SJed Brown }
1923ba337c44SJed Brown 
1924ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
1925ba337c44SJed Brown {
1926ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1927ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1928ba337c44SJed Brown   PetscScalar  *aa = a->v;
1929ba337c44SJed Brown 
1930ba337c44SJed Brown   PetscFunctionBegin;
1931ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
1932ba337c44SJed Brown   PetscFunctionReturn(0);
1933ba337c44SJed Brown }
1934ba337c44SJed Brown 
1935ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
1936ba337c44SJed Brown {
1937ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1938ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1939ba337c44SJed Brown   PetscScalar  *aa = a->v;
1940ba337c44SJed Brown 
1941ba337c44SJed Brown   PetscFunctionBegin;
1942ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1943ba337c44SJed Brown   PetscFunctionReturn(0);
1944ba337c44SJed Brown }
1945284134d9SBarry Smith 
1946a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
1947150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
1948a9fe9ddaSSatish Balay {
1949a9fe9ddaSSatish Balay   PetscErrorCode ierr;
1950a9fe9ddaSSatish Balay 
1951a9fe9ddaSSatish Balay   PetscFunctionBegin;
1952a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
19533ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
1954a9fe9ddaSSatish Balay     ierr = MatMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
19553ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
1956a9fe9ddaSSatish Balay   }
19573ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
1958a9fe9ddaSSatish Balay   ierr = MatMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
19593ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
1960a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
1961a9fe9ddaSSatish Balay }
1962a9fe9ddaSSatish Balay 
1963a9fe9ddaSSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
1964a9fe9ddaSSatish Balay {
1965ee16a9a1SHong Zhang   PetscErrorCode ierr;
1966d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
1967ee16a9a1SHong Zhang   Mat            Cmat;
1968a9fe9ddaSSatish Balay 
1969ee16a9a1SHong Zhang   PetscFunctionBegin;
1970e32f2f54SBarry 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);
1971ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
1972ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
1973ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
19740298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
1975d73949e8SHong Zhang 
1976ee16a9a1SHong Zhang   *C = Cmat;
1977ee16a9a1SHong Zhang   PetscFunctionReturn(0);
1978ee16a9a1SHong Zhang }
1979a9fe9ddaSSatish Balay 
1980a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
1981a9fe9ddaSSatish Balay {
1982a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1983a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
1984a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
19850805154bSBarry Smith   PetscBLASInt   m,n,k;
1986a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
1987c5df96a5SBarry Smith   PetscErrorCode ierr;
1988fd4e9aacSBarry Smith   PetscBool      flg;
1989a9fe9ddaSSatish Balay 
1990a9fe9ddaSSatish Balay   PetscFunctionBegin;
1991fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQDENSE,&flg);CHKERRQ(ierr);
1992fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Second matrix must be dense");
1993fd4e9aacSBarry Smith 
1994fd4e9aacSBarry Smith   /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/
1995fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
1996fd4e9aacSBarry Smith   if (flg) {
1997fd4e9aacSBarry Smith     C->ops->matmultnumeric = MatMatMultNumeric_SeqAIJ_SeqDense;
1998fd4e9aacSBarry Smith     ierr = (*C->ops->matmultnumeric)(A,B,C);CHKERRQ(ierr);
1999fd4e9aacSBarry Smith     PetscFunctionReturn(0);
2000fd4e9aacSBarry Smith   }
2001fd4e9aacSBarry Smith 
2002fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&flg);CHKERRQ(ierr);
2003fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"First matrix must be dense");
20048208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
20058208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2006c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
20075ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2008a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2009a9fe9ddaSSatish Balay }
2010a9fe9ddaSSatish Balay 
201169f65d41SStefano Zampini PetscErrorCode MatMatTransposeMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
201269f65d41SStefano Zampini {
201369f65d41SStefano Zampini   PetscErrorCode ierr;
201469f65d41SStefano Zampini 
201569f65d41SStefano Zampini   PetscFunctionBegin;
201669f65d41SStefano Zampini   if (scall == MAT_INITIAL_MATRIX) {
201769f65d41SStefano Zampini     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
201869f65d41SStefano Zampini     ierr = MatMatTransposeMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
201969f65d41SStefano Zampini     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
202069f65d41SStefano Zampini   }
202169f65d41SStefano Zampini   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
202269f65d41SStefano Zampini   ierr = MatMatTransposeMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
202369f65d41SStefano Zampini   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
202469f65d41SStefano Zampini   PetscFunctionReturn(0);
202569f65d41SStefano Zampini }
202669f65d41SStefano Zampini 
202769f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
202869f65d41SStefano Zampini {
202969f65d41SStefano Zampini   PetscErrorCode ierr;
203069f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
203169f65d41SStefano Zampini   Mat            Cmat;
203269f65d41SStefano Zampini 
203369f65d41SStefano Zampini   PetscFunctionBegin;
203469f65d41SStefano Zampini   if (A->cmap->n != B->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->cmap->n %d != B->cmap->n %d\n",A->cmap->n,B->cmap->n);
203569f65d41SStefano Zampini   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
203669f65d41SStefano Zampini   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
203769f65d41SStefano Zampini   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
203869f65d41SStefano Zampini   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
203969f65d41SStefano Zampini 
204069f65d41SStefano Zampini   Cmat->assembled = PETSC_TRUE;
204169f65d41SStefano Zampini 
204269f65d41SStefano Zampini   *C = Cmat;
204369f65d41SStefano Zampini   PetscFunctionReturn(0);
204469f65d41SStefano Zampini }
204569f65d41SStefano Zampini 
204669f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
204769f65d41SStefano Zampini {
204869f65d41SStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
204969f65d41SStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
205069f65d41SStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
205169f65d41SStefano Zampini   PetscBLASInt   m,n,k;
205269f65d41SStefano Zampini   PetscScalar    _DOne=1.0,_DZero=0.0;
205369f65d41SStefano Zampini   PetscErrorCode ierr;
205469f65d41SStefano Zampini 
205569f65d41SStefano Zampini   PetscFunctionBegin;
205669f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
205769f65d41SStefano Zampini   ierr = PetscBLASIntCast(B->rmap->n,&n);CHKERRQ(ierr);
205869f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
205969f65d41SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
206069f65d41SStefano Zampini   PetscFunctionReturn(0);
206169f65d41SStefano Zampini }
206269f65d41SStefano Zampini 
206375648e8dSHong Zhang PetscErrorCode MatTransposeMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
2064a9fe9ddaSSatish Balay {
2065a9fe9ddaSSatish Balay   PetscErrorCode ierr;
2066a9fe9ddaSSatish Balay 
2067a9fe9ddaSSatish Balay   PetscFunctionBegin;
2068a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
20693ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
207075648e8dSHong Zhang     ierr = MatTransposeMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
20713ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2072a9fe9ddaSSatish Balay   }
20733ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
207475648e8dSHong Zhang   ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
20753ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2076a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2077a9fe9ddaSSatish Balay }
2078a9fe9ddaSSatish Balay 
207975648e8dSHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
2080a9fe9ddaSSatish Balay {
2081ee16a9a1SHong Zhang   PetscErrorCode ierr;
2082d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
2083ee16a9a1SHong Zhang   Mat            Cmat;
2084a9fe9ddaSSatish Balay 
2085ee16a9a1SHong Zhang   PetscFunctionBegin;
2086e32f2f54SBarry 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);
2087ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
2088ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
2089ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
20900298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
20912205254eSKarl Rupp 
2092ee16a9a1SHong Zhang   Cmat->assembled = PETSC_TRUE;
20932205254eSKarl Rupp 
2094ee16a9a1SHong Zhang   *C = Cmat;
2095ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2096ee16a9a1SHong Zhang }
2097a9fe9ddaSSatish Balay 
209875648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2099a9fe9ddaSSatish Balay {
2100a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2101a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2102a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
21030805154bSBarry Smith   PetscBLASInt   m,n,k;
2104a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
2105c5df96a5SBarry Smith   PetscErrorCode ierr;
2106a9fe9ddaSSatish Balay 
2107a9fe9ddaSSatish Balay   PetscFunctionBegin;
21088208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
21098208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2110c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
21115ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2112a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2113a9fe9ddaSSatish Balay }
2114985db425SBarry Smith 
2115e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2116985db425SBarry Smith {
2117985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2118985db425SBarry Smith   PetscErrorCode ierr;
2119d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
2120985db425SBarry Smith   PetscScalar    *x;
2121985db425SBarry Smith   MatScalar      *aa = a->v;
2122985db425SBarry Smith 
2123985db425SBarry Smith   PetscFunctionBegin;
2124e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2125985db425SBarry Smith 
2126985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2127985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2128985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2129e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2130985db425SBarry Smith   for (i=0; i<m; i++) {
2131985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2132985db425SBarry Smith     for (j=1; j<n; j++) {
2133985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
2134985db425SBarry Smith     }
2135985db425SBarry Smith   }
2136985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2137985db425SBarry Smith   PetscFunctionReturn(0);
2138985db425SBarry Smith }
2139985db425SBarry Smith 
2140e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2141985db425SBarry Smith {
2142985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2143985db425SBarry Smith   PetscErrorCode ierr;
2144d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
2145985db425SBarry Smith   PetscScalar    *x;
2146985db425SBarry Smith   PetscReal      atmp;
2147985db425SBarry Smith   MatScalar      *aa = a->v;
2148985db425SBarry Smith 
2149985db425SBarry Smith   PetscFunctionBegin;
2150e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2151985db425SBarry Smith 
2152985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2153985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2154985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2155e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2156985db425SBarry Smith   for (i=0; i<m; i++) {
21579189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2158985db425SBarry Smith     for (j=1; j<n; j++) {
2159985db425SBarry Smith       atmp = PetscAbsScalar(aa[i+m*j]);
2160985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2161985db425SBarry Smith     }
2162985db425SBarry Smith   }
2163985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2164985db425SBarry Smith   PetscFunctionReturn(0);
2165985db425SBarry Smith }
2166985db425SBarry Smith 
2167e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2168985db425SBarry Smith {
2169985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2170985db425SBarry Smith   PetscErrorCode ierr;
2171d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
2172985db425SBarry Smith   PetscScalar    *x;
2173985db425SBarry Smith   MatScalar      *aa = a->v;
2174985db425SBarry Smith 
2175985db425SBarry Smith   PetscFunctionBegin;
2176e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2177985db425SBarry Smith 
2178985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2179985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2180985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2181e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2182985db425SBarry Smith   for (i=0; i<m; i++) {
2183985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2184985db425SBarry Smith     for (j=1; j<n; j++) {
2185985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
2186985db425SBarry Smith     }
2187985db425SBarry Smith   }
2188985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2189985db425SBarry Smith   PetscFunctionReturn(0);
2190985db425SBarry Smith }
2191985db425SBarry Smith 
2192e0877f53SBarry Smith static PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
21938d0534beSBarry Smith {
21948d0534beSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
21958d0534beSBarry Smith   PetscErrorCode ierr;
21968d0534beSBarry Smith   PetscScalar    *x;
21978d0534beSBarry Smith 
21988d0534beSBarry Smith   PetscFunctionBegin;
2199e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
22008d0534beSBarry Smith 
22018d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2202d0f46423SBarry Smith   ierr = PetscMemcpy(x,a->v+col*a->lda,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
22038d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
22048d0534beSBarry Smith   PetscFunctionReturn(0);
22058d0534beSBarry Smith }
22068d0534beSBarry Smith 
22070716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
22080716a85fSBarry Smith {
22090716a85fSBarry Smith   PetscErrorCode ierr;
22100716a85fSBarry Smith   PetscInt       i,j,m,n;
22110716a85fSBarry Smith   PetscScalar    *a;
22120716a85fSBarry Smith 
22130716a85fSBarry Smith   PetscFunctionBegin;
22140716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
22150716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
22168c778c55SBarry Smith   ierr = MatDenseGetArray(A,&a);CHKERRQ(ierr);
22170716a85fSBarry Smith   if (type == NORM_2) {
22180716a85fSBarry Smith     for (i=0; i<n; i++) {
22190716a85fSBarry Smith       for (j=0; j<m; j++) {
22200716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
22210716a85fSBarry Smith       }
22220716a85fSBarry Smith       a += m;
22230716a85fSBarry Smith     }
22240716a85fSBarry Smith   } else if (type == NORM_1) {
22250716a85fSBarry Smith     for (i=0; i<n; i++) {
22260716a85fSBarry Smith       for (j=0; j<m; j++) {
22270716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
22280716a85fSBarry Smith       }
22290716a85fSBarry Smith       a += m;
22300716a85fSBarry Smith     }
22310716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
22320716a85fSBarry Smith     for (i=0; i<n; i++) {
22330716a85fSBarry Smith       for (j=0; j<m; j++) {
22340716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
22350716a85fSBarry Smith       }
22360716a85fSBarry Smith       a += m;
22370716a85fSBarry Smith     }
2238ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
22398c778c55SBarry Smith   ierr = MatDenseRestoreArray(A,&a);CHKERRQ(ierr);
22400716a85fSBarry Smith   if (type == NORM_2) {
22418f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
22420716a85fSBarry Smith   }
22430716a85fSBarry Smith   PetscFunctionReturn(0);
22440716a85fSBarry Smith }
22450716a85fSBarry Smith 
224673a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
224773a71a0fSBarry Smith {
224873a71a0fSBarry Smith   PetscErrorCode ierr;
224973a71a0fSBarry Smith   PetscScalar    *a;
225073a71a0fSBarry Smith   PetscInt       m,n,i;
225173a71a0fSBarry Smith 
225273a71a0fSBarry Smith   PetscFunctionBegin;
225373a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
22548c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
225573a71a0fSBarry Smith   for (i=0; i<m*n; i++) {
225673a71a0fSBarry Smith     ierr = PetscRandomGetValue(rctx,a+i);CHKERRQ(ierr);
225773a71a0fSBarry Smith   }
22588c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
225973a71a0fSBarry Smith   PetscFunctionReturn(0);
226073a71a0fSBarry Smith }
226173a71a0fSBarry Smith 
22623b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
22633b49f96aSBarry Smith {
22643b49f96aSBarry Smith   PetscFunctionBegin;
22653b49f96aSBarry Smith   *missing = PETSC_FALSE;
22663b49f96aSBarry Smith   PetscFunctionReturn(0);
22673b49f96aSBarry Smith }
226873a71a0fSBarry Smith 
2269af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
227086aefd0dSHong Zhang {
227186aefd0dSHong Zhang   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
227286aefd0dSHong Zhang 
227386aefd0dSHong Zhang   PetscFunctionBegin;
227486aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
227586aefd0dSHong Zhang   *vals = a->v+col*a->lda;
227686aefd0dSHong Zhang   PetscFunctionReturn(0);
227786aefd0dSHong Zhang }
227886aefd0dSHong Zhang 
2279af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
228086aefd0dSHong Zhang {
228186aefd0dSHong Zhang   PetscFunctionBegin;
228286aefd0dSHong Zhang   *vals = 0; /* user cannot accidently use the array later */
228386aefd0dSHong Zhang   PetscFunctionReturn(0);
228486aefd0dSHong Zhang }
2285abc3b08eSStefano Zampini 
2286289bc588SBarry Smith /* -------------------------------------------------------------------*/
2287a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2288905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2289905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2290905e6a2fSBarry Smith                                         MatMult_SeqDense,
229197304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
22927c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
22937c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2294db4efbfdSBarry Smith                                         0,
2295db4efbfdSBarry Smith                                         0,
2296db4efbfdSBarry Smith                                         0,
2297db4efbfdSBarry Smith                                 /* 10*/ 0,
2298905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2299905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
230041f059aeSBarry Smith                                         MatSOR_SeqDense,
2301ec8511deSBarry Smith                                         MatTranspose_SeqDense,
230297304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2303905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2304905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2305905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2306905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2307c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2308c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2309905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2310905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2311d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2312db4efbfdSBarry Smith                                         0,
2313db4efbfdSBarry Smith                                         0,
2314db4efbfdSBarry Smith                                         0,
2315db4efbfdSBarry Smith                                         0,
23164994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2317273d9f13SBarry Smith                                         0,
2318905e6a2fSBarry Smith                                         0,
231973a71a0fSBarry Smith                                         0,
232073a71a0fSBarry Smith                                         0,
2321d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2322a5ae1ecdSBarry Smith                                         0,
2323a5ae1ecdSBarry Smith                                         0,
2324a5ae1ecdSBarry Smith                                         0,
2325a5ae1ecdSBarry Smith                                         0,
2326d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
23277dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2328a5ae1ecdSBarry Smith                                         0,
23294b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2330a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2331d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2332a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
23337d68702bSBarry Smith                                         MatShift_Basic,
2334a5ae1ecdSBarry Smith                                         0,
23353f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
233673a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2337a5ae1ecdSBarry Smith                                         0,
2338a5ae1ecdSBarry Smith                                         0,
2339a5ae1ecdSBarry Smith                                         0,
2340a5ae1ecdSBarry Smith                                         0,
2341d519adbfSMatthew Knepley                                 /* 54*/ 0,
2342a5ae1ecdSBarry Smith                                         0,
2343a5ae1ecdSBarry Smith                                         0,
2344a5ae1ecdSBarry Smith                                         0,
2345a5ae1ecdSBarry Smith                                         0,
2346d519adbfSMatthew Knepley                                 /* 59*/ 0,
2347e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2348e03a110bSBarry Smith                                         MatView_SeqDense,
2349357abbc8SBarry Smith                                         0,
235097304618SKris Buschelman                                         0,
2351d519adbfSMatthew Knepley                                 /* 64*/ 0,
235297304618SKris Buschelman                                         0,
235397304618SKris Buschelman                                         0,
235497304618SKris Buschelman                                         0,
235597304618SKris Buschelman                                         0,
2356d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
235797304618SKris Buschelman                                         0,
235897304618SKris Buschelman                                         0,
235997304618SKris Buschelman                                         0,
236097304618SKris Buschelman                                         0,
2361d519adbfSMatthew Knepley                                 /* 74*/ 0,
236297304618SKris Buschelman                                         0,
236397304618SKris Buschelman                                         0,
236497304618SKris Buschelman                                         0,
236597304618SKris Buschelman                                         0,
2366d519adbfSMatthew Knepley                                 /* 79*/ 0,
236797304618SKris Buschelman                                         0,
236897304618SKris Buschelman                                         0,
236997304618SKris Buschelman                                         0,
23705bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2371865e5f61SKris Buschelman                                         0,
23721cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2373865e5f61SKris Buschelman                                         0,
2374865e5f61SKris Buschelman                                         0,
2375865e5f61SKris Buschelman                                         0,
2376d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqDense_SeqDense,
2377a9fe9ddaSSatish Balay                                         MatMatMultSymbolic_SeqDense_SeqDense,
2378a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2379abc3b08eSStefano Zampini                                         MatPtAP_SeqDense_SeqDense,
2380abc3b08eSStefano Zampini                                         MatPtAPSymbolic_SeqDense_SeqDense,
2381abc3b08eSStefano Zampini                                 /* 94*/ MatPtAPNumeric_SeqDense_SeqDense,
238269f65d41SStefano Zampini                                         MatMatTransposeMult_SeqDense_SeqDense,
238369f65d41SStefano Zampini                                         MatMatTransposeMultSymbolic_SeqDense_SeqDense,
238469f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2385284134d9SBarry Smith                                         0,
2386d519adbfSMatthew Knepley                                 /* 99*/ 0,
2387284134d9SBarry Smith                                         0,
2388284134d9SBarry Smith                                         0,
2389ba337c44SJed Brown                                         MatConjugate_SeqDense,
2390f73d5cc4SBarry Smith                                         0,
2391ba337c44SJed Brown                                 /*104*/ 0,
2392ba337c44SJed Brown                                         MatRealPart_SeqDense,
2393ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2394985db425SBarry Smith                                         0,
2395985db425SBarry Smith                                         0,
23968208b9aeSStefano Zampini                                 /*109*/ 0,
2397985db425SBarry Smith                                         0,
23988d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2399aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
24003b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2401aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2402aabbc4fbSShri Abhyankar                                         0,
2403aabbc4fbSShri Abhyankar                                         0,
2404aabbc4fbSShri Abhyankar                                         0,
2405aabbc4fbSShri Abhyankar                                         0,
2406aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2407aabbc4fbSShri Abhyankar                                         0,
2408aabbc4fbSShri Abhyankar                                         0,
24090716a85fSBarry Smith                                         0,
24100716a85fSBarry Smith                                         0,
24110716a85fSBarry Smith                                 /*124*/ 0,
24125df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
24135df89d91SHong Zhang                                         0,
24145df89d91SHong Zhang                                         0,
24155df89d91SHong Zhang                                         0,
24165df89d91SHong Zhang                                 /*129*/ 0,
241775648e8dSHong Zhang                                         MatTransposeMatMult_SeqDense_SeqDense,
241875648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqDense_SeqDense,
241975648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
24203964eb88SJed Brown                                         0,
24213964eb88SJed Brown                                 /*134*/ 0,
24223964eb88SJed Brown                                         0,
24233964eb88SJed Brown                                         0,
24243964eb88SJed Brown                                         0,
24253964eb88SJed Brown                                         0,
24263964eb88SJed Brown                                 /*139*/ 0,
2427f9426fe0SMark Adams                                         0,
2428*d528f656SJakub Kruzik                                         0,
2429*d528f656SJakub Kruzik                                         0,
2430*d528f656SJakub Kruzik                                         0,
2431*d528f656SJakub Kruzik                                 /*144*/ MatCreateMPIMatConcatenateSeqMat_SeqDense
2432985db425SBarry Smith };
243390ace30eSBarry Smith 
24344b828684SBarry Smith /*@C
2435fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2436d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2437d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2438289bc588SBarry Smith 
2439db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2440db81eaa0SLois Curfman McInnes 
244120563c6bSBarry Smith    Input Parameters:
2442db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
24430c775827SLois Curfman McInnes .  m - number of rows
244418f449edSLois Curfman McInnes .  n - number of columns
24450298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2446dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
244720563c6bSBarry Smith 
244820563c6bSBarry Smith    Output Parameter:
244944cd7ae7SLois Curfman McInnes .  A - the matrix
245020563c6bSBarry Smith 
2451b259b22eSLois Curfman McInnes    Notes:
245218f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
245318f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
24540298fd71SBarry Smith    set data=NULL.
245518f449edSLois Curfman McInnes 
2456027ccd11SLois Curfman McInnes    Level: intermediate
2457027ccd11SLois Curfman McInnes 
2458dbd7a890SLois Curfman McInnes .keywords: dense, matrix, LAPACK, BLAS
2459d65003e9SLois Curfman McInnes 
246069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
246120563c6bSBarry Smith @*/
24627087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2463289bc588SBarry Smith {
2464dfbe8321SBarry Smith   PetscErrorCode ierr;
24653b2fbd54SBarry Smith 
24663a40ed3dSBarry Smith   PetscFunctionBegin;
2467f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2468f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2469273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2470273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2471273d9f13SBarry Smith   PetscFunctionReturn(0);
2472273d9f13SBarry Smith }
2473273d9f13SBarry Smith 
2474273d9f13SBarry Smith /*@C
2475273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2476273d9f13SBarry Smith 
2477273d9f13SBarry Smith    Collective on MPI_Comm
2478273d9f13SBarry Smith 
2479273d9f13SBarry Smith    Input Parameters:
24801c4f3114SJed Brown +  B - the matrix
24810298fd71SBarry Smith -  data - the array (or NULL)
2482273d9f13SBarry Smith 
2483273d9f13SBarry Smith    Notes:
2484273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2485273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2486284134d9SBarry Smith    need not call this routine.
2487273d9f13SBarry Smith 
2488273d9f13SBarry Smith    Level: intermediate
2489273d9f13SBarry Smith 
2490273d9f13SBarry Smith .keywords: dense, matrix, LAPACK, BLAS
2491273d9f13SBarry Smith 
249269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA()
2493867c911aSBarry Smith 
2494273d9f13SBarry Smith @*/
24957087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2496273d9f13SBarry Smith {
24974ac538c5SBarry Smith   PetscErrorCode ierr;
2498a23d5eceSKris Buschelman 
2499a23d5eceSKris Buschelman   PetscFunctionBegin;
25004ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2501a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2502a23d5eceSKris Buschelman }
2503a23d5eceSKris Buschelman 
25047087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2505a23d5eceSKris Buschelman {
2506273d9f13SBarry Smith   Mat_SeqDense   *b;
2507dfbe8321SBarry Smith   PetscErrorCode ierr;
2508273d9f13SBarry Smith 
2509273d9f13SBarry Smith   PetscFunctionBegin;
2510273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2511a868139aSShri Abhyankar 
251234ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
251334ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
251434ef9618SShri Abhyankar 
2515273d9f13SBarry Smith   b       = (Mat_SeqDense*)B->data;
251686d161a7SShri Abhyankar   b->Mmax = B->rmap->n;
251786d161a7SShri Abhyankar   b->Nmax = B->cmap->n;
251886d161a7SShri Abhyankar   if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n;
251986d161a7SShri Abhyankar 
2520220afb94SBarry Smith   ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr);
25219e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
25229e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2523e92229d0SSatish Balay     ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr);
25243bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
25252205254eSKarl Rupp 
25269e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2527273d9f13SBarry Smith   } else { /* user-allocated storage */
25289e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2529273d9f13SBarry Smith     b->v          = data;
2530273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2531273d9f13SBarry Smith   }
25320450473dSBarry Smith   B->assembled = PETSC_TRUE;
2533273d9f13SBarry Smith   PetscFunctionReturn(0);
2534273d9f13SBarry Smith }
2535273d9f13SBarry Smith 
253665b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2537cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
25388baccfbdSHong Zhang {
2539d77f618aSHong Zhang   Mat            mat_elemental;
2540d77f618aSHong Zhang   PetscErrorCode ierr;
2541d77f618aSHong Zhang   PetscScalar    *array,*v_colwise;
2542d77f618aSHong Zhang   PetscInt       M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2543d77f618aSHong Zhang 
25448baccfbdSHong Zhang   PetscFunctionBegin;
2545d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
2546d77f618aSHong Zhang   ierr = MatDenseGetArray(A,&array);CHKERRQ(ierr);
2547d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2548d77f618aSHong Zhang   k = 0;
2549d77f618aSHong Zhang   for (j=0; j<N; j++) {
2550d77f618aSHong Zhang     cols[j] = j;
2551d77f618aSHong Zhang     for (i=0; i<M; i++) {
2552d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2553d77f618aSHong Zhang     }
2554d77f618aSHong Zhang   }
2555d77f618aSHong Zhang   for (i=0; i<M; i++) {
2556d77f618aSHong Zhang     rows[i] = i;
2557d77f618aSHong Zhang   }
2558d77f618aSHong Zhang   ierr = MatDenseRestoreArray(A,&array);CHKERRQ(ierr);
2559d77f618aSHong Zhang 
2560d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2561d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2562d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2563d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2564d77f618aSHong Zhang 
2565d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2566d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2567d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2568d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2569d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2570d77f618aSHong Zhang 
2571511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
257228be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2573d77f618aSHong Zhang   } else {
2574d77f618aSHong Zhang     *newmat = mat_elemental;
2575d77f618aSHong Zhang   }
25768baccfbdSHong Zhang   PetscFunctionReturn(0);
25778baccfbdSHong Zhang }
257865b80a83SHong Zhang #endif
25798baccfbdSHong Zhang 
25801b807ce4Svictorle /*@C
25811b807ce4Svictorle   MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array
25821b807ce4Svictorle 
25831b807ce4Svictorle   Input parameter:
25841b807ce4Svictorle + A - the matrix
25851b807ce4Svictorle - lda - the leading dimension
25861b807ce4Svictorle 
25871b807ce4Svictorle   Notes:
2588867c911aSBarry Smith   This routine is to be used in conjunction with MatSeqDenseSetPreallocation();
25891b807ce4Svictorle   it asserts that the preallocation has a leading dimension (the LDA parameter
25901b807ce4Svictorle   of Blas and Lapack fame) larger than M, the first dimension of the matrix.
25911b807ce4Svictorle 
25921b807ce4Svictorle   Level: intermediate
25931b807ce4Svictorle 
25941b807ce4Svictorle .keywords: dense, matrix, LAPACK, BLAS
25951b807ce4Svictorle 
2596284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize()
2597867c911aSBarry Smith 
25981b807ce4Svictorle @*/
25997087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetLDA(Mat B,PetscInt lda)
26001b807ce4Svictorle {
26011b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
260221a2c019SBarry Smith 
26031b807ce4Svictorle   PetscFunctionBegin;
2604e32f2f54SBarry 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);
26051b807ce4Svictorle   b->lda       = lda;
260621a2c019SBarry Smith   b->changelda = PETSC_FALSE;
260721a2c019SBarry Smith   b->Mmax      = PetscMax(b->Mmax,lda);
26081b807ce4Svictorle   PetscFunctionReturn(0);
26091b807ce4Svictorle }
26101b807ce4Svictorle 
2611*d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
2612*d528f656SJakub Kruzik {
2613*d528f656SJakub Kruzik   PetscErrorCode ierr;
2614*d528f656SJakub Kruzik   PetscMPIInt    size;
2615*d528f656SJakub Kruzik 
2616*d528f656SJakub Kruzik   PetscFunctionBegin;
2617*d528f656SJakub Kruzik   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2618*d528f656SJakub Kruzik   if (size == 1) {
2619*d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
2620*d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
2621*d528f656SJakub Kruzik     } else {
2622*d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2623*d528f656SJakub Kruzik     }
2624*d528f656SJakub Kruzik   } else {
2625*d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
2626*d528f656SJakub Kruzik   }
2627*d528f656SJakub Kruzik   PetscFunctionReturn(0);
2628*d528f656SJakub Kruzik }
2629*d528f656SJakub Kruzik 
26300bad9183SKris Buschelman /*MC
2631fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
26320bad9183SKris Buschelman 
26330bad9183SKris Buschelman    Options Database Keys:
26340bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
26350bad9183SKris Buschelman 
26360bad9183SKris Buschelman   Level: beginner
26370bad9183SKris Buschelman 
263889665df3SBarry Smith .seealso: MatCreateSeqDense()
263989665df3SBarry Smith 
26400bad9183SKris Buschelman M*/
26410bad9183SKris Buschelman 
26428cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqDense(Mat B)
2643273d9f13SBarry Smith {
2644273d9f13SBarry Smith   Mat_SeqDense   *b;
2645dfbe8321SBarry Smith   PetscErrorCode ierr;
26467c334f02SBarry Smith   PetscMPIInt    size;
2647273d9f13SBarry Smith 
2648273d9f13SBarry Smith   PetscFunctionBegin;
2649ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
2650e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
265155659b69SBarry Smith 
2652b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
2653549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
265444cd7ae7SLois Curfman McInnes   B->data = (void*)b;
265518f449edSLois Curfman McInnes 
2656273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
26574e220ebcSLois Curfman McInnes 
2658bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
26598572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2660d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
2661d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
26628572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2663bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2664bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
26658baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
26668baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
26678baccfbdSHong Zhang #endif
2668bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
2669bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaij_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2670bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2671bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2672abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaij_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
26734099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijperm_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
26744099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijperm_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
26754099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijperm_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
26764099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijperm_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
267796e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijmkl_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
267896e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijmkl_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
267996e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijmkl_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
268096e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijmkl_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
268196e6d5c4SRichard Tran Mills 
26823bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaij_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
26833bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
26843bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
26854099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijperm_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
26864099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
26874099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
268896e6d5c4SRichard Tran Mills 
268996e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijmkl_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
269096e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
269196e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2692af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
2693af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
269417667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
26953a40ed3dSBarry Smith   PetscFunctionReturn(0);
2696289bc588SBarry Smith }
269786aefd0dSHong Zhang 
269886aefd0dSHong Zhang /*@C
2699af53bab2SHong Zhang    MatDenseGetColumn - gives access to a column of a dense matrix. This is only the local part of the column. You MUST call MatDenseRestoreColumn() to avoid memory bleeding.
270086aefd0dSHong Zhang 
270186aefd0dSHong Zhang    Not Collective
270286aefd0dSHong Zhang 
270386aefd0dSHong Zhang    Input Parameter:
270486aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
270586aefd0dSHong Zhang -  col - column index
270686aefd0dSHong Zhang 
270786aefd0dSHong Zhang    Output Parameter:
270886aefd0dSHong Zhang .  vals - pointer to the data
270986aefd0dSHong Zhang 
271086aefd0dSHong Zhang    Level: intermediate
271186aefd0dSHong Zhang 
271286aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
271386aefd0dSHong Zhang @*/
271486aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
271586aefd0dSHong Zhang {
271686aefd0dSHong Zhang   PetscErrorCode ierr;
271786aefd0dSHong Zhang 
271886aefd0dSHong Zhang   PetscFunctionBegin;
271986aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
272086aefd0dSHong Zhang   PetscFunctionReturn(0);
272186aefd0dSHong Zhang }
272286aefd0dSHong Zhang 
272386aefd0dSHong Zhang /*@C
272486aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
272586aefd0dSHong Zhang 
272686aefd0dSHong Zhang    Not Collective
272786aefd0dSHong Zhang 
272886aefd0dSHong Zhang    Input Parameter:
272986aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
273086aefd0dSHong Zhang 
273186aefd0dSHong Zhang    Output Parameter:
273286aefd0dSHong Zhang .  vals - pointer to the data
273386aefd0dSHong Zhang 
273486aefd0dSHong Zhang    Level: intermediate
273586aefd0dSHong Zhang 
273686aefd0dSHong Zhang .seealso: MatDenseGetColumn()
273786aefd0dSHong Zhang @*/
273886aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
273986aefd0dSHong Zhang {
274086aefd0dSHong Zhang   PetscErrorCode ierr;
274186aefd0dSHong Zhang 
274286aefd0dSHong Zhang   PetscFunctionBegin;
274386aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
274486aefd0dSHong Zhang   PetscFunctionReturn(0);
274586aefd0dSHong Zhang }
2746