xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 49d0e96416d3ddb38db4a5c04e2b85849f5b3a59)
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     }
5400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
558c178816SStefano Zampini     PetscStackCallBLAS("LAPACKgetri",LAPACKgetri_(&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
5600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
578c178816SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr); /* TODO CHECK FLOPS */
588c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
598c178816SStefano Zampini     if (A->spd) {
6000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
618c178816SStefano Zampini       PetscStackCallBLAS("LAPACKpotri",LAPACKpotri_("L",&n,mat->v,&mat->lda,&info));
6200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
638c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
648c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
658c178816SStefano Zampini     } else if (A->hermitian) {
668c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
678c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
6800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
698c178816SStefano Zampini       PetscStackCallBLAS("LAPACKhetri",LAPACKhetri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
7000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
718c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
728c178816SStefano Zampini #endif
738c178816SStefano Zampini     } else { /* symmetric case */
748c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
758c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
7600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
778c178816SStefano Zampini       PetscStackCallBLAS("LAPACKsytri",LAPACKsytri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
7800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
798c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_FALSE);CHKERRQ(ierr);
808c178816SStefano Zampini     }
818c178816SStefano Zampini     if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad Inversion: zero pivot in row %D",(PetscInt)info-1);
828c178816SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr); /* TODO CHECK FLOPS */
838c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
848c178816SStefano Zampini #endif
858c178816SStefano Zampini 
868c178816SStefano Zampini   A->ops->solve             = NULL;
878c178816SStefano Zampini   A->ops->matsolve          = NULL;
888c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
898c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
908c178816SStefano Zampini   A->ops->solveadd          = NULL;
918c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
928c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
938c178816SStefano Zampini   ierr                      = PetscFree(A->solvertype);CHKERRQ(ierr);
948c178816SStefano Zampini   PetscFunctionReturn(0);
958c178816SStefano Zampini }
968c178816SStefano Zampini 
973f49a652SStefano Zampini PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
983f49a652SStefano Zampini {
993f49a652SStefano Zampini   PetscErrorCode    ierr;
1003f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1013f49a652SStefano Zampini   PetscInt          m  = l->lda, n = A->cmap->n,r = A->rmap->n, i,j;
1023f49a652SStefano Zampini   PetscScalar       *slot,*bb;
1033f49a652SStefano Zampini   const PetscScalar *xx;
1043f49a652SStefano Zampini 
1053f49a652SStefano Zampini   PetscFunctionBegin;
1063f49a652SStefano Zampini #if defined(PETSC_USE_DEBUG)
1073f49a652SStefano Zampini   for (i=0; i<N; i++) {
1083f49a652SStefano Zampini     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1093f49a652SStefano 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);
1103f49a652SStefano 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);
1113f49a652SStefano Zampini   }
1123f49a652SStefano Zampini #endif
1133f49a652SStefano Zampini 
1143f49a652SStefano Zampini   /* fix right hand side if needed */
1153f49a652SStefano Zampini   if (x && b) {
1163f49a652SStefano Zampini     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1173f49a652SStefano Zampini     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
1183f49a652SStefano Zampini     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
1193f49a652SStefano Zampini     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1203f49a652SStefano Zampini     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
1213f49a652SStefano Zampini   }
1223f49a652SStefano Zampini 
1233f49a652SStefano Zampini   for (i=0; i<N; i++) {
1243f49a652SStefano Zampini     slot = l->v + rows[i]*m;
1253f49a652SStefano Zampini     ierr = PetscMemzero(slot,r*sizeof(PetscScalar));CHKERRQ(ierr);
1263f49a652SStefano Zampini   }
1273f49a652SStefano Zampini   for (i=0; i<N; i++) {
1283f49a652SStefano Zampini     slot = l->v + rows[i];
1293f49a652SStefano Zampini     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
1303f49a652SStefano Zampini   }
1313f49a652SStefano Zampini   if (diag != 0.0) {
1323f49a652SStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1333f49a652SStefano Zampini     for (i=0; i<N; i++) {
1343f49a652SStefano Zampini       slot  = l->v + (m+1)*rows[i];
1353f49a652SStefano Zampini       *slot = diag;
1363f49a652SStefano Zampini     }
1373f49a652SStefano Zampini   }
1383f49a652SStefano Zampini   PetscFunctionReturn(0);
1393f49a652SStefano Zampini }
1403f49a652SStefano Zampini 
141abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C)
142abc3b08eSStefano Zampini {
143abc3b08eSStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)(C->data);
144abc3b08eSStefano Zampini   PetscErrorCode ierr;
145abc3b08eSStefano Zampini 
146abc3b08eSStefano Zampini   PetscFunctionBegin;
147abc3b08eSStefano Zampini   ierr = MatMatMultNumeric_SeqDense_SeqDense(A,P,c->ptapwork);CHKERRQ(ierr);
148abc3b08eSStefano Zampini   ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(P,c->ptapwork,C);CHKERRQ(ierr);
149abc3b08eSStefano Zampini   PetscFunctionReturn(0);
150abc3b08eSStefano Zampini }
151abc3b08eSStefano Zampini 
152abc3b08eSStefano Zampini PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat *C)
153abc3b08eSStefano Zampini {
154abc3b08eSStefano Zampini   Mat_SeqDense   *c;
155abc3b08eSStefano Zampini   PetscErrorCode ierr;
156abc3b08eSStefano Zampini 
157abc3b08eSStefano Zampini   PetscFunctionBegin;
158abc3b08eSStefano Zampini   ierr = MatCreateSeqDense(PetscObjectComm((PetscObject)A),P->cmap->N,P->cmap->N,NULL,C);CHKERRQ(ierr);
159abc3b08eSStefano Zampini   c = (Mat_SeqDense*)((*C)->data);
160abc3b08eSStefano Zampini   ierr = MatCreateSeqDense(PetscObjectComm((PetscObject)A),A->rmap->N,P->cmap->N,NULL,&c->ptapwork);CHKERRQ(ierr);
161abc3b08eSStefano Zampini   PetscFunctionReturn(0);
162abc3b08eSStefano Zampini }
163abc3b08eSStefano Zampini 
164150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatPtAP_SeqDense_SeqDense(Mat A,Mat P,MatReuse reuse,PetscReal fill,Mat *C)
165abc3b08eSStefano Zampini {
166abc3b08eSStefano Zampini   PetscErrorCode ierr;
167abc3b08eSStefano Zampini 
168abc3b08eSStefano Zampini   PetscFunctionBegin;
169abc3b08eSStefano Zampini   if (reuse == MAT_INITIAL_MATRIX) {
170abc3b08eSStefano Zampini     ierr = MatPtAPSymbolic_SeqDense_SeqDense(A,P,fill,C);CHKERRQ(ierr);
171abc3b08eSStefano Zampini   }
172abc3b08eSStefano Zampini   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
173abc3b08eSStefano Zampini   ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
174abc3b08eSStefano Zampini   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
175abc3b08eSStefano Zampini   PetscFunctionReturn(0);
176abc3b08eSStefano Zampini }
177abc3b08eSStefano Zampini 
178cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
179b49cda9fSStefano Zampini {
180a13144ffSStefano Zampini   Mat            B = NULL;
181b49cda9fSStefano Zampini   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
182b49cda9fSStefano Zampini   Mat_SeqDense   *b;
183b49cda9fSStefano Zampini   PetscErrorCode ierr;
184b49cda9fSStefano Zampini   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i;
185b49cda9fSStefano Zampini   MatScalar      *av=a->a;
186a13144ffSStefano Zampini   PetscBool      isseqdense;
187b49cda9fSStefano Zampini 
188b49cda9fSStefano Zampini   PetscFunctionBegin;
189a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
190a13144ffSStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense);CHKERRQ(ierr);
191a13144ffSStefano Zampini     if (!isseqdense) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type);
192a13144ffSStefano Zampini   }
193a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
194b49cda9fSStefano Zampini     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
195b49cda9fSStefano Zampini     ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
196b49cda9fSStefano Zampini     ierr = MatSetType(B,MATSEQDENSE);CHKERRQ(ierr);
197b49cda9fSStefano Zampini     ierr = MatSeqDenseSetPreallocation(B,NULL);CHKERRQ(ierr);
198b49cda9fSStefano Zampini     b    = (Mat_SeqDense*)(B->data);
199a13144ffSStefano Zampini   } else {
200a13144ffSStefano Zampini     b    = (Mat_SeqDense*)((*newmat)->data);
201a13144ffSStefano Zampini     ierr = PetscMemzero(b->v,m*n*sizeof(PetscScalar));CHKERRQ(ierr);
202a13144ffSStefano Zampini   }
203b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
204b49cda9fSStefano Zampini     PetscInt j;
205b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
206b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
207b49cda9fSStefano Zampini       aj++;
208b49cda9fSStefano Zampini       av++;
209b49cda9fSStefano Zampini     }
210b49cda9fSStefano Zampini     ai++;
211b49cda9fSStefano Zampini   }
212b49cda9fSStefano Zampini 
213511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
214a13144ffSStefano Zampini     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
215a13144ffSStefano Zampini     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
21628be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
217b49cda9fSStefano Zampini   } else {
218a13144ffSStefano Zampini     if (B) *newmat = B;
219a13144ffSStefano Zampini     ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
220a13144ffSStefano Zampini     ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
221b49cda9fSStefano Zampini   }
222b49cda9fSStefano Zampini   PetscFunctionReturn(0);
223b49cda9fSStefano Zampini }
224b49cda9fSStefano Zampini 
225cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
2266a63e612SBarry Smith {
2276a63e612SBarry Smith   Mat            B;
2286a63e612SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2296a63e612SBarry Smith   PetscErrorCode ierr;
2309399e1b8SMatthew G. Knepley   PetscInt       i, j;
2319399e1b8SMatthew G. Knepley   PetscInt       *rows, *nnz;
2329399e1b8SMatthew G. Knepley   MatScalar      *aa = a->v, *vals;
2336a63e612SBarry Smith 
2346a63e612SBarry Smith   PetscFunctionBegin;
235ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
2366a63e612SBarry Smith   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
2376a63e612SBarry Smith   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
2389399e1b8SMatthew G. Knepley   ierr = PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals);CHKERRQ(ierr);
2399399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2409399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) ++nnz[i];
2416a63e612SBarry Smith     aa += a->lda;
2426a63e612SBarry Smith   }
2439399e1b8SMatthew G. Knepley   ierr = MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz);CHKERRQ(ierr);
2449399e1b8SMatthew G. Knepley   aa = a->v;
2459399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2469399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2479399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) {rows[numRows] = i; vals[numRows++] = aa[i];}
2489399e1b8SMatthew G. Knepley     ierr = MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr);
2499399e1b8SMatthew G. Knepley     aa  += a->lda;
2509399e1b8SMatthew G. Knepley   }
2519399e1b8SMatthew G. Knepley   ierr = PetscFree3(rows,nnz,vals);CHKERRQ(ierr);
2526a63e612SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2536a63e612SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2546a63e612SBarry Smith 
255511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
25628be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
2576a63e612SBarry Smith   } else {
2586a63e612SBarry Smith     *newmat = B;
2596a63e612SBarry Smith   }
2606a63e612SBarry Smith   PetscFunctionReturn(0);
2616a63e612SBarry Smith }
2626a63e612SBarry Smith 
263e0877f53SBarry Smith static PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
2641987afe7SBarry Smith {
2651987afe7SBarry Smith   Mat_SeqDense   *x     = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
266f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
26713f74950SBarry Smith   PetscInt       j;
2680805154bSBarry Smith   PetscBLASInt   N,m,ldax,lday,one = 1;
269efee365bSSatish Balay   PetscErrorCode ierr;
2703a40ed3dSBarry Smith 
2713a40ed3dSBarry Smith   PetscFunctionBegin;
272c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n*X->cmap->n,&N);CHKERRQ(ierr);
273c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n,&m);CHKERRQ(ierr);
274c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->lda,&ldax);CHKERRQ(ierr);
275c5df96a5SBarry Smith   ierr = PetscBLASIntCast(y->lda,&lday);CHKERRQ(ierr);
276a5ce6ee0Svictorle   if (ldax>m || lday>m) {
277d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
2788b83055fSJed Brown       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&oalpha,x->v+j*ldax,&one,y->v+j*lday,&one));
279a5ce6ee0Svictorle     }
280a5ce6ee0Svictorle   } else {
2818b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&oalpha,x->v,&one,y->v,&one));
282a5ce6ee0Svictorle   }
283a3fa217bSJose E. Roman   ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr);
2840450473dSBarry Smith   ierr = PetscLogFlops(PetscMax(2*N-1,0));CHKERRQ(ierr);
2853a40ed3dSBarry Smith   PetscFunctionReturn(0);
2861987afe7SBarry Smith }
2871987afe7SBarry Smith 
288e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
289289bc588SBarry Smith {
290d0f46423SBarry Smith   PetscInt N = A->rmap->n*A->cmap->n;
2913a40ed3dSBarry Smith 
2923a40ed3dSBarry Smith   PetscFunctionBegin;
2934e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
2944e220ebcSLois Curfman McInnes   info->nz_allocated      = (double)N;
2956de62eeeSBarry Smith   info->nz_used           = (double)N;
2966de62eeeSBarry Smith   info->nz_unneeded       = (double)0;
2974e220ebcSLois Curfman McInnes   info->assemblies        = (double)A->num_ass;
2984e220ebcSLois Curfman McInnes   info->mallocs           = 0;
2997adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3004e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3014e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3024e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3033a40ed3dSBarry Smith   PetscFunctionReturn(0);
304289bc588SBarry Smith }
305289bc588SBarry Smith 
306e0877f53SBarry Smith static PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
30780cd9d93SLois Curfman McInnes {
308273d9f13SBarry Smith   Mat_SeqDense   *a     = (Mat_SeqDense*)A->data;
309f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
310efee365bSSatish Balay   PetscErrorCode ierr;
311c5df96a5SBarry Smith   PetscBLASInt   one = 1,j,nz,lda;
31280cd9d93SLois Curfman McInnes 
3133a40ed3dSBarry Smith   PetscFunctionBegin;
314c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->lda,&lda);CHKERRQ(ierr);
315d0f46423SBarry Smith   if (lda>A->rmap->n) {
316c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n,&nz);CHKERRQ(ierr);
317d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
3188b83055fSJed Brown       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&oalpha,a->v+j*lda,&one));
319a5ce6ee0Svictorle     }
320a5ce6ee0Svictorle   } else {
321c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz);CHKERRQ(ierr);
3228b83055fSJed Brown     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&oalpha,a->v,&one));
323a5ce6ee0Svictorle   }
324efee365bSSatish Balay   ierr = PetscLogFlops(nz);CHKERRQ(ierr);
3253a40ed3dSBarry Smith   PetscFunctionReturn(0);
32680cd9d93SLois Curfman McInnes }
32780cd9d93SLois Curfman McInnes 
328e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3291cbb95d3SBarry Smith {
3301cbb95d3SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
331d0f46423SBarry Smith   PetscInt     i,j,m = A->rmap->n,N;
3321cbb95d3SBarry Smith   PetscScalar  *v = a->v;
3331cbb95d3SBarry Smith 
3341cbb95d3SBarry Smith   PetscFunctionBegin;
3351cbb95d3SBarry Smith   *fl = PETSC_FALSE;
336d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3371cbb95d3SBarry Smith   N = a->lda;
3381cbb95d3SBarry Smith 
3391cbb95d3SBarry Smith   for (i=0; i<m; i++) {
3401cbb95d3SBarry Smith     for (j=i+1; j<m; j++) {
3411cbb95d3SBarry Smith       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) PetscFunctionReturn(0);
3421cbb95d3SBarry Smith     }
3431cbb95d3SBarry Smith   }
3441cbb95d3SBarry Smith   *fl = PETSC_TRUE;
3451cbb95d3SBarry Smith   PetscFunctionReturn(0);
3461cbb95d3SBarry Smith }
3471cbb95d3SBarry Smith 
348e0877f53SBarry Smith static PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
349b24902e0SBarry Smith {
350b24902e0SBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data,*l;
351b24902e0SBarry Smith   PetscErrorCode ierr;
352b24902e0SBarry Smith   PetscInt       lda = (PetscInt)mat->lda,j,m;
353b24902e0SBarry Smith 
354b24902e0SBarry Smith   PetscFunctionBegin;
355aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr);
356aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr);
3570298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr);
358b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
359b24902e0SBarry Smith     l = (Mat_SeqDense*)newi->data;
360d0f46423SBarry Smith     if (lda>A->rmap->n) {
361d0f46423SBarry Smith       m = A->rmap->n;
362d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
363b24902e0SBarry Smith         ierr = PetscMemcpy(l->v+j*m,mat->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr);
364b24902e0SBarry Smith       }
365b24902e0SBarry Smith     } else {
366d0f46423SBarry Smith       ierr = PetscMemcpy(l->v,mat->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
367b24902e0SBarry Smith     }
368b24902e0SBarry Smith   }
369b24902e0SBarry Smith   newi->assembled = PETSC_TRUE;
370b24902e0SBarry Smith   PetscFunctionReturn(0);
371b24902e0SBarry Smith }
372b24902e0SBarry Smith 
373e0877f53SBarry Smith static PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
37402cad45dSBarry Smith {
3756849ba73SBarry Smith   PetscErrorCode ierr;
37602cad45dSBarry Smith 
3773a40ed3dSBarry Smith   PetscFunctionBegin;
378ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr);
379d0f46423SBarry Smith   ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
3805c9eb25fSBarry Smith   ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
381719d5645SBarry Smith   ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr);
382b24902e0SBarry Smith   PetscFunctionReturn(0);
383b24902e0SBarry Smith }
384b24902e0SBarry Smith 
3856ee01492SSatish Balay 
386e0877f53SBarry Smith static PetscErrorCode MatLUFactor_SeqDense(Mat,IS,IS,const MatFactorInfo*);
387719d5645SBarry Smith 
388e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
389289bc588SBarry Smith {
3904482741eSBarry Smith   MatFactorInfo  info;
391a093e273SMatthew Knepley   PetscErrorCode ierr;
3923a40ed3dSBarry Smith 
3933a40ed3dSBarry Smith   PetscFunctionBegin;
394c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
395719d5645SBarry Smith   ierr = MatLUFactor_SeqDense(fact,0,0,&info);CHKERRQ(ierr);
3963a40ed3dSBarry Smith   PetscFunctionReturn(0);
397289bc588SBarry Smith }
3986ee01492SSatish Balay 
399e0877f53SBarry Smith static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy)
400289bc588SBarry Smith {
401c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
4026849ba73SBarry Smith   PetscErrorCode    ierr;
403f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
404f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
405c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
40667e560aaSBarry Smith 
4073a40ed3dSBarry Smith   PetscFunctionBegin;
408c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
409f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4101ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
411d0f46423SBarry Smith   ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
412d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_LU) {
413ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
414e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
415ae7cfcebSSatish Balay #else
41600121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4178b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
41800121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
419e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
420ae7cfcebSSatish Balay #endif
421d5f3da31SBarry Smith   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
422ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
423e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
424ae7cfcebSSatish Balay #else
425a49dc2a2SStefano Zampini     if (A->spd) {
42600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4278b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
42800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
429e32f2f54SBarry Smith       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
430a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
431a49dc2a2SStefano Zampini     } else if (A->hermitian) {
43200121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
433a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
43400121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
435a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
436a49dc2a2SStefano Zampini #endif
437a49dc2a2SStefano Zampini     } else { /* symmetric case */
43800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
439a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
44000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
441a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
442a49dc2a2SStefano Zampini     }
443ae7cfcebSSatish Balay #endif
4442205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
445f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4461ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
447dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
4483a40ed3dSBarry Smith   PetscFunctionReturn(0);
449289bc588SBarry Smith }
4506ee01492SSatish Balay 
451e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X)
45285e2c93fSHong Zhang {
45385e2c93fSHong Zhang   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
45485e2c93fSHong Zhang   PetscErrorCode ierr;
45585e2c93fSHong Zhang   PetscScalar    *b,*x;
456efb80c78SLisandro Dalcin   PetscInt       n;
457783b601eSJed Brown   PetscBLASInt   nrhs,info,m;
458bda8bf91SBarry Smith   PetscBool      flg;
45985e2c93fSHong Zhang 
46085e2c93fSHong Zhang   PetscFunctionBegin;
461c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
4620298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
463ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
4640298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
465ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
466bda8bf91SBarry Smith 
4670298fd71SBarry Smith   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
468c5df96a5SBarry Smith   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
4698c778c55SBarry Smith   ierr = MatDenseGetArray(B,&b);CHKERRQ(ierr);
4708c778c55SBarry Smith   ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr);
47185e2c93fSHong Zhang 
472f272c775SHong Zhang   ierr = PetscMemcpy(x,b,m*nrhs*sizeof(PetscScalar));CHKERRQ(ierr);
47385e2c93fSHong Zhang 
47485e2c93fSHong Zhang   if (A->factortype == MAT_FACTOR_LU) {
47585e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_GETRS)
47685e2c93fSHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
47785e2c93fSHong Zhang #else
47800121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4798b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
48000121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
48185e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
48285e2c93fSHong Zhang #endif
48385e2c93fSHong Zhang   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
48485e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_POTRS)
48585e2c93fSHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
48685e2c93fSHong Zhang #else
487a49dc2a2SStefano Zampini     if (A->spd) {
48800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4898b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
49000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
49185e2c93fSHong Zhang       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
492a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
493a49dc2a2SStefano Zampini     } else if (A->hermitian) {
49400121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
495a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
49600121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
497a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
498a49dc2a2SStefano Zampini #endif
499a49dc2a2SStefano Zampini     } else { /* symmetric case */
50000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
501a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
50200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
503a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
504a49dc2a2SStefano Zampini     }
50585e2c93fSHong Zhang #endif
5062205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
50785e2c93fSHong Zhang 
5088c778c55SBarry Smith   ierr = MatDenseRestoreArray(B,&b);CHKERRQ(ierr);
5098c778c55SBarry Smith   ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr);
51085e2c93fSHong Zhang   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
51185e2c93fSHong Zhang   PetscFunctionReturn(0);
51285e2c93fSHong Zhang }
51385e2c93fSHong Zhang 
51400121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
51500121966SStefano Zampini 
516e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
517da3a660dSBarry Smith {
518c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
519dfbe8321SBarry Smith   PetscErrorCode    ierr;
520f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
521f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
522c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
52367e560aaSBarry Smith 
5243a40ed3dSBarry Smith   PetscFunctionBegin;
525c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
526f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5271ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
528d0f46423SBarry Smith   ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
5298208b9aeSStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
530ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
531e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
532ae7cfcebSSatish Balay #else
53300121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5348b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
53500121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
536e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve");
537ae7cfcebSSatish Balay #endif
5388208b9aeSStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
539ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
540e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
541ae7cfcebSSatish Balay #else
542a49dc2a2SStefano Zampini     if (A->spd) {
54300121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
54400121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
54500121966SStefano Zampini #endif
54600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5478b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
54800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
54900121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
55000121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
55100121966SStefano Zampini #endif
552a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
553a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
554a49dc2a2SStefano Zampini     } else if (A->hermitian) {
55500121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
55600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
55700121966SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
55800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
55900121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
560ae7cfcebSSatish Balay #endif
561a49dc2a2SStefano Zampini     } else { /* symmetric case */
56200121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
563a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
56400121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
565a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
566da3a660dSBarry Smith     }
567a49dc2a2SStefano Zampini #endif
568a49dc2a2SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
569f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5701ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
571dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
5723a40ed3dSBarry Smith   PetscFunctionReturn(0);
573da3a660dSBarry Smith }
5746ee01492SSatish Balay 
575e0877f53SBarry Smith static PetscErrorCode MatSolveAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
576da3a660dSBarry Smith {
577dfbe8321SBarry Smith   PetscErrorCode    ierr;
578f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
579f1ceaac6SMatthew G. Knepley   PetscScalar       *y,sone = 1.0;
580da3a660dSBarry Smith   Vec               tmp = 0;
58167e560aaSBarry Smith 
5823a40ed3dSBarry Smith   PetscFunctionBegin;
583f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5841ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
585d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
586da3a660dSBarry Smith   if (yy == zz) {
58778b31e54SBarry Smith     ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr);
5883bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)tmp);CHKERRQ(ierr);
58978b31e54SBarry Smith     ierr = VecCopy(yy,tmp);CHKERRQ(ierr);
590da3a660dSBarry Smith   }
5918208b9aeSStefano Zampini   ierr = MatSolve_SeqDense(A,xx,yy);CHKERRQ(ierr);
5926bf464f9SBarry Smith   if (tmp) {
5936bf464f9SBarry Smith     ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr);
5946bf464f9SBarry Smith     ierr = VecDestroy(&tmp);CHKERRQ(ierr);
5956bf464f9SBarry Smith   } else {
5966bf464f9SBarry Smith     ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr);
5976bf464f9SBarry Smith   }
598f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5991ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
6008208b9aeSStefano Zampini   ierr = PetscLogFlops(A->cmap->n);CHKERRQ(ierr);
6013a40ed3dSBarry Smith   PetscFunctionReturn(0);
602da3a660dSBarry Smith }
60367e560aaSBarry Smith 
604e0877f53SBarry Smith static PetscErrorCode MatSolveTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
605da3a660dSBarry Smith {
6066849ba73SBarry Smith   PetscErrorCode    ierr;
607f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
608f1ceaac6SMatthew G. Knepley   PetscScalar       *y,sone = 1.0;
60989ae1891SBarry Smith   Vec               tmp = NULL;
61067e560aaSBarry Smith 
6113a40ed3dSBarry Smith   PetscFunctionBegin;
612d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
613f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
6141ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
615da3a660dSBarry Smith   if (yy == zz) {
61678b31e54SBarry Smith     ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr);
6173bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)tmp);CHKERRQ(ierr);
61878b31e54SBarry Smith     ierr = VecCopy(yy,tmp);CHKERRQ(ierr);
619da3a660dSBarry Smith   }
6208208b9aeSStefano Zampini   ierr = MatSolveTranspose_SeqDense(A,xx,yy);CHKERRQ(ierr);
62190f02eecSBarry Smith   if (tmp) {
6222dcb1b2aSMatthew Knepley     ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr);
6236bf464f9SBarry Smith     ierr = VecDestroy(&tmp);CHKERRQ(ierr);
6243a40ed3dSBarry Smith   } else {
6252dcb1b2aSMatthew Knepley     ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr);
62690f02eecSBarry Smith   }
627f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
6281ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
6298208b9aeSStefano Zampini   ierr = PetscLogFlops(A->cmap->n);CHKERRQ(ierr);
6303a40ed3dSBarry Smith   PetscFunctionReturn(0);
631da3a660dSBarry Smith }
632db4efbfdSBarry Smith 
633db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
634db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
635db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
636e0877f53SBarry Smith static PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
637db4efbfdSBarry Smith {
638db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_GETRF)
639db4efbfdSBarry Smith   PetscFunctionBegin;
640e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRF - Lapack routine is unavailable.");
641db4efbfdSBarry Smith #else
642db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
643db4efbfdSBarry Smith   PetscErrorCode ierr;
644db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
645db4efbfdSBarry Smith 
646db4efbfdSBarry Smith   PetscFunctionBegin;
647c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
648c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
649db4efbfdSBarry Smith   if (!mat->pivots) {
6508208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
6513bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
652db4efbfdSBarry Smith   }
653db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
6548e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6558b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
6568e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
6578e57ea43SSatish Balay 
658e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
659e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
6608208b9aeSStefano Zampini 
661db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6628208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
663db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
664db4efbfdSBarry Smith   A->ops->solveadd          = MatSolveAdd_SeqDense;
665db4efbfdSBarry Smith   A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
666d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
667db4efbfdSBarry Smith 
668f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
669f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
670f6224b95SHong Zhang 
671dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
672db4efbfdSBarry Smith #endif
673db4efbfdSBarry Smith   PetscFunctionReturn(0);
674db4efbfdSBarry Smith }
675db4efbfdSBarry Smith 
676a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
677e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
678db4efbfdSBarry Smith {
679db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_POTRF)
680db4efbfdSBarry Smith   PetscFunctionBegin;
681e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF - Lapack routine is unavailable.");
682db4efbfdSBarry Smith #else
683db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
684db4efbfdSBarry Smith   PetscErrorCode ierr;
685c5df96a5SBarry Smith   PetscBLASInt   info,n;
686db4efbfdSBarry Smith 
687db4efbfdSBarry Smith   PetscFunctionBegin;
688c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
689db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
690a49dc2a2SStefano Zampini   if (A->spd) {
69100121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6928b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
69300121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
694a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
695a49dc2a2SStefano Zampini   } else if (A->hermitian) {
696a49dc2a2SStefano Zampini     if (!mat->pivots) {
697a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
698a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
699a49dc2a2SStefano Zampini     }
700a49dc2a2SStefano Zampini     if (!mat->fwork) {
701a49dc2a2SStefano Zampini       PetscScalar dummy;
702a49dc2a2SStefano Zampini 
703a49dc2a2SStefano Zampini       mat->lfwork = -1;
70400121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
705a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
70600121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
707a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
708a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
709a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
710a49dc2a2SStefano Zampini     }
71100121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
712a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
71300121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
714a49dc2a2SStefano Zampini #endif
715a49dc2a2SStefano Zampini   } else { /* symmetric case */
716a49dc2a2SStefano Zampini     if (!mat->pivots) {
717a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
718a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
719a49dc2a2SStefano Zampini     }
720a49dc2a2SStefano Zampini     if (!mat->fwork) {
721a49dc2a2SStefano Zampini       PetscScalar dummy;
722a49dc2a2SStefano Zampini 
723a49dc2a2SStefano Zampini       mat->lfwork = -1;
72400121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
725a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
72600121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
727a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
728a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
729a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
730a49dc2a2SStefano Zampini     }
73100121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
732a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
73300121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
734a49dc2a2SStefano Zampini   }
735e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
7368208b9aeSStefano Zampini 
737db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
7388208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
739db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
740db4efbfdSBarry Smith   A->ops->solveadd          = MatSolveAdd_SeqDense;
741db4efbfdSBarry Smith   A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
742d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
7432205254eSKarl Rupp 
744f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
745f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
746f6224b95SHong Zhang 
747eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
748db4efbfdSBarry Smith #endif
749db4efbfdSBarry Smith   PetscFunctionReturn(0);
750db4efbfdSBarry Smith }
751db4efbfdSBarry Smith 
752db4efbfdSBarry Smith 
7530481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
754db4efbfdSBarry Smith {
755db4efbfdSBarry Smith   PetscErrorCode ierr;
756db4efbfdSBarry Smith   MatFactorInfo  info;
757db4efbfdSBarry Smith 
758db4efbfdSBarry Smith   PetscFunctionBegin;
759db4efbfdSBarry Smith   info.fill = 1.0;
7602205254eSKarl Rupp 
761c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
762719d5645SBarry Smith   ierr = MatCholeskyFactor_SeqDense(fact,0,&info);CHKERRQ(ierr);
763db4efbfdSBarry Smith   PetscFunctionReturn(0);
764db4efbfdSBarry Smith }
765db4efbfdSBarry Smith 
766e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
767db4efbfdSBarry Smith {
768db4efbfdSBarry Smith   PetscFunctionBegin;
769c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
7701bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
771719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
772bd443b22SStefano Zampini   fact->ops->solve                 = MatSolve_SeqDense;
773bd443b22SStefano Zampini   fact->ops->matsolve              = MatMatSolve_SeqDense;
774bd443b22SStefano Zampini   fact->ops->solvetranspose        = MatSolveTranspose_SeqDense;
775bd443b22SStefano Zampini   fact->ops->solveadd              = MatSolveAdd_SeqDense;
776bd443b22SStefano Zampini   fact->ops->solvetransposeadd     = MatSolveTransposeAdd_SeqDense;
777db4efbfdSBarry Smith   PetscFunctionReturn(0);
778db4efbfdSBarry Smith }
779db4efbfdSBarry Smith 
780e0877f53SBarry Smith static PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
781db4efbfdSBarry Smith {
782db4efbfdSBarry Smith   PetscFunctionBegin;
783b66fe19dSMatthew G Knepley   fact->preallocated           = PETSC_TRUE;
784c3ef05f6SHong Zhang   fact->assembled              = PETSC_TRUE;
785719d5645SBarry Smith   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
786bd443b22SStefano Zampini   fact->ops->solve             = MatSolve_SeqDense;
787bd443b22SStefano Zampini   fact->ops->matsolve          = MatMatSolve_SeqDense;
788bd443b22SStefano Zampini   fact->ops->solvetranspose    = MatSolveTranspose_SeqDense;
789bd443b22SStefano Zampini   fact->ops->solveadd          = MatSolveAdd_SeqDense;
790bd443b22SStefano Zampini   fact->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
791db4efbfdSBarry Smith   PetscFunctionReturn(0);
792db4efbfdSBarry Smith }
793db4efbfdSBarry Smith 
794cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
795db4efbfdSBarry Smith {
796db4efbfdSBarry Smith   PetscErrorCode ierr;
797db4efbfdSBarry Smith 
798db4efbfdSBarry Smith   PetscFunctionBegin;
799ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
800db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
801db4efbfdSBarry Smith   ierr = MatSetType(*fact,((PetscObject)A)->type_name);CHKERRQ(ierr);
802db4efbfdSBarry Smith   if (ftype == MAT_FACTOR_LU) {
803db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
804db4efbfdSBarry Smith   } else {
805db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
806db4efbfdSBarry Smith   }
807d5f3da31SBarry Smith   (*fact)->factortype = ftype;
80800c67f3bSHong Zhang 
80900c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
81000c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
811db4efbfdSBarry Smith   PetscFunctionReturn(0);
812db4efbfdSBarry Smith }
813db4efbfdSBarry Smith 
814289bc588SBarry Smith /* ------------------------------------------------------------------*/
815e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
816289bc588SBarry Smith {
817c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
818d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
819d9ca1df4SBarry Smith   const PetscScalar *b;
820dfbe8321SBarry Smith   PetscErrorCode    ierr;
821d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
822c5df96a5SBarry Smith   PetscBLASInt      o = 1,bm;
823289bc588SBarry Smith 
8243a40ed3dSBarry Smith   PetscFunctionBegin;
825422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
826c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
827289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
8283bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
8292dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
830289bc588SBarry Smith   }
8311ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
832d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
833b965ef7fSBarry Smith   its  = its*lits;
834e32f2f54SBarry 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);
835289bc588SBarry Smith   while (its--) {
836fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
837289bc588SBarry Smith       for (i=0; i<m; i++) {
8383bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
83955a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
840289bc588SBarry Smith       }
841289bc588SBarry Smith     }
842fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
843289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
8443bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
84555a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
846289bc588SBarry Smith       }
847289bc588SBarry Smith     }
848289bc588SBarry Smith   }
849d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
8501ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
8513a40ed3dSBarry Smith   PetscFunctionReturn(0);
852289bc588SBarry Smith }
853289bc588SBarry Smith 
854289bc588SBarry Smith /* -----------------------------------------------------------------*/
855cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
856289bc588SBarry Smith {
857c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
858d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
859d9ca1df4SBarry Smith   PetscScalar       *y;
860dfbe8321SBarry Smith   PetscErrorCode    ierr;
8610805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
862ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
8633a40ed3dSBarry Smith 
8643a40ed3dSBarry Smith   PetscFunctionBegin;
865c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
866c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
867d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8681ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8695ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8705ac36cfcSBarry Smith     PetscBLASInt i;
8715ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
8725ac36cfcSBarry Smith   } else {
8738b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
8745ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
8755ac36cfcSBarry Smith   }
876d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8771ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8783a40ed3dSBarry Smith   PetscFunctionReturn(0);
879289bc588SBarry Smith }
880800995b7SMatthew Knepley 
881cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
882289bc588SBarry Smith {
883c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
884d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
885dfbe8321SBarry Smith   PetscErrorCode    ierr;
8860805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
887d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
8883a40ed3dSBarry Smith 
8893a40ed3dSBarry Smith   PetscFunctionBegin;
890c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
891c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
892d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8931ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8945ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8955ac36cfcSBarry Smith     PetscBLASInt i;
8965ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
8975ac36cfcSBarry Smith   } else {
8988b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
8995ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
9005ac36cfcSBarry Smith   }
901d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
9021ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9033a40ed3dSBarry Smith   PetscFunctionReturn(0);
904289bc588SBarry Smith }
9056ee01492SSatish Balay 
906cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
907289bc588SBarry Smith {
908c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
909d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
910d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
911dfbe8321SBarry Smith   PetscErrorCode    ierr;
9120805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
9133a40ed3dSBarry Smith 
9143a40ed3dSBarry Smith   PetscFunctionBegin;
915c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
916c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
917d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
918600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
919d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
9201ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9218b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
922d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
9231ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
924dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
9253a40ed3dSBarry Smith   PetscFunctionReturn(0);
926289bc588SBarry Smith }
9276ee01492SSatish Balay 
928e0877f53SBarry Smith static PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
929289bc588SBarry Smith {
930c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
931d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
932d9ca1df4SBarry Smith   PetscScalar       *y;
933dfbe8321SBarry Smith   PetscErrorCode    ierr;
9340805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
93587828ca2SBarry Smith   PetscScalar       _DOne=1.0;
9363a40ed3dSBarry Smith 
9373a40ed3dSBarry Smith   PetscFunctionBegin;
938c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
939c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
940d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
941600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
942d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
9431ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9448b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
945d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
9461ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
947dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
9483a40ed3dSBarry Smith   PetscFunctionReturn(0);
949289bc588SBarry Smith }
950289bc588SBarry Smith 
951289bc588SBarry Smith /* -----------------------------------------------------------------*/
952e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
953289bc588SBarry Smith {
954c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
95587828ca2SBarry Smith   PetscScalar    *v;
9566849ba73SBarry Smith   PetscErrorCode ierr;
95713f74950SBarry Smith   PetscInt       i;
95867e560aaSBarry Smith 
9593a40ed3dSBarry Smith   PetscFunctionBegin;
960d0f46423SBarry Smith   *ncols = A->cmap->n;
961289bc588SBarry Smith   if (cols) {
962854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
963d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
964289bc588SBarry Smith   }
965289bc588SBarry Smith   if (vals) {
966854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
967289bc588SBarry Smith     v    = mat->v + row;
968d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
969289bc588SBarry Smith   }
9703a40ed3dSBarry Smith   PetscFunctionReturn(0);
971289bc588SBarry Smith }
9726ee01492SSatish Balay 
973e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
974289bc588SBarry Smith {
975dfbe8321SBarry Smith   PetscErrorCode ierr;
9766e111a19SKarl Rupp 
977606d414cSSatish Balay   PetscFunctionBegin;
978606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
979606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
9803a40ed3dSBarry Smith   PetscFunctionReturn(0);
981289bc588SBarry Smith }
982289bc588SBarry Smith /* ----------------------------------------------------------------*/
983e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
984289bc588SBarry Smith {
985c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
98613f74950SBarry Smith   PetscInt     i,j,idx=0;
987d6dfbf8fSBarry Smith 
9883a40ed3dSBarry Smith   PetscFunctionBegin;
989289bc588SBarry Smith   if (!mat->roworiented) {
990dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
991289bc588SBarry Smith       for (j=0; j<n; j++) {
992cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
9932515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
994e32f2f54SBarry 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);
99558804f6dSBarry Smith #endif
996289bc588SBarry Smith         for (i=0; i<m; i++) {
997cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
9982515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
999e32f2f54SBarry 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);
100058804f6dSBarry Smith #endif
1001cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1002289bc588SBarry Smith         }
1003289bc588SBarry Smith       }
10043a40ed3dSBarry Smith     } else {
1005289bc588SBarry Smith       for (j=0; j<n; j++) {
1006cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
10072515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1008e32f2f54SBarry 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);
100958804f6dSBarry Smith #endif
1010289bc588SBarry Smith         for (i=0; i<m; i++) {
1011cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
10122515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1013e32f2f54SBarry 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);
101458804f6dSBarry Smith #endif
1015cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1016289bc588SBarry Smith         }
1017289bc588SBarry Smith       }
1018289bc588SBarry Smith     }
10193a40ed3dSBarry Smith   } else {
1020dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1021e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
1022cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
10232515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1024e32f2f54SBarry 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);
102558804f6dSBarry Smith #endif
1026e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
1027cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
10282515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1029e32f2f54SBarry 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);
103058804f6dSBarry Smith #endif
1031cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1032e8d4e0b9SBarry Smith         }
1033e8d4e0b9SBarry Smith       }
10343a40ed3dSBarry Smith     } else {
1035289bc588SBarry Smith       for (i=0; i<m; i++) {
1036cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
10372515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1038e32f2f54SBarry 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);
103958804f6dSBarry Smith #endif
1040289bc588SBarry Smith         for (j=0; j<n; j++) {
1041cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
10422515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1043e32f2f54SBarry 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);
104458804f6dSBarry Smith #endif
1045cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1046289bc588SBarry Smith         }
1047289bc588SBarry Smith       }
1048289bc588SBarry Smith     }
1049e8d4e0b9SBarry Smith   }
10503a40ed3dSBarry Smith   PetscFunctionReturn(0);
1051289bc588SBarry Smith }
1052e8d4e0b9SBarry Smith 
1053e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1054ae80bb75SLois Curfman McInnes {
1055ae80bb75SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
105613f74950SBarry Smith   PetscInt     i,j;
1057ae80bb75SLois Curfman McInnes 
10583a40ed3dSBarry Smith   PetscFunctionBegin;
1059ae80bb75SLois Curfman McInnes   /* row-oriented output */
1060ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
106197e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1062e32f2f54SBarry 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);
1063ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
10646f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1065e32f2f54SBarry 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);
106697e567efSBarry Smith       *v++ = mat->v[indexn[j]*mat->lda + indexm[i]];
1067ae80bb75SLois Curfman McInnes     }
1068ae80bb75SLois Curfman McInnes   }
10693a40ed3dSBarry Smith   PetscFunctionReturn(0);
1070ae80bb75SLois Curfman McInnes }
1071ae80bb75SLois Curfman McInnes 
1072289bc588SBarry Smith /* -----------------------------------------------------------------*/
1073289bc588SBarry Smith 
1074e0877f53SBarry Smith static PetscErrorCode MatLoad_SeqDense(Mat newmat,PetscViewer viewer)
1075aabbc4fbSShri Abhyankar {
1076aabbc4fbSShri Abhyankar   Mat_SeqDense   *a;
1077aabbc4fbSShri Abhyankar   PetscErrorCode ierr;
1078aabbc4fbSShri Abhyankar   PetscInt       *scols,i,j,nz,header[4];
1079aabbc4fbSShri Abhyankar   int            fd;
1080aabbc4fbSShri Abhyankar   PetscMPIInt    size;
1081aabbc4fbSShri Abhyankar   PetscInt       *rowlengths = 0,M,N,*cols,grows,gcols;
1082aabbc4fbSShri Abhyankar   PetscScalar    *vals,*svals,*v,*w;
1083ce94432eSBarry Smith   MPI_Comm       comm;
10847f489da9SVaclav Hapla   PetscBool      isbinary;
1085aabbc4fbSShri Abhyankar 
1086aabbc4fbSShri Abhyankar   PetscFunctionBegin;
10877f489da9SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
10887f489da9SVaclav Hapla   if (!isbinary) SETERRQ2(PetscObjectComm((PetscObject)newmat),PETSC_ERR_SUP,"Viewer type %s not yet supported for reading %s matrices",((PetscObject)viewer)->type_name,((PetscObject)newmat)->type_name);
10897f489da9SVaclav Hapla 
1090c98fd787SBarry Smith   /* force binary viewer to load .info file if it has not yet done so */
1091c98fd787SBarry Smith   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1092ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
1093aabbc4fbSShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1094aabbc4fbSShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"view must have one processor");
1095aabbc4fbSShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
1096aabbc4fbSShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
1097aabbc4fbSShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not matrix object");
1098aabbc4fbSShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
1099aabbc4fbSShri Abhyankar 
1100aabbc4fbSShri Abhyankar   /* set global size if not set already*/
1101aabbc4fbSShri Abhyankar   if (newmat->rmap->n < 0 && newmat->rmap->N < 0 && newmat->cmap->n < 0 && newmat->cmap->N < 0) {
1102aabbc4fbSShri Abhyankar     ierr = MatSetSizes(newmat,M,N,M,N);CHKERRQ(ierr);
1103aabbc4fbSShri Abhyankar   } else {
1104aabbc4fbSShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
1105aabbc4fbSShri Abhyankar     ierr = MatGetSize(newmat,&grows,&gcols);CHKERRQ(ierr);
1106aabbc4fbSShri 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);
1107aabbc4fbSShri Abhyankar   }
1108e6324fbbSBarry Smith   a = (Mat_SeqDense*)newmat->data;
1109e6324fbbSBarry Smith   if (!a->user_alloc) {
11100298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1111e6324fbbSBarry Smith   }
1112aabbc4fbSShri Abhyankar 
1113aabbc4fbSShri Abhyankar   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense */
1114aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
1115aabbc4fbSShri Abhyankar     v = a->v;
1116aabbc4fbSShri Abhyankar     /* Allocate some temp space to read in the values and then flip them
1117aabbc4fbSShri Abhyankar        from row major to column major */
1118854ce69bSBarry Smith     ierr = PetscMalloc1(M*N > 0 ? M*N : 1,&w);CHKERRQ(ierr);
1119aabbc4fbSShri Abhyankar     /* read in nonzero values */
1120aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,w,M*N,PETSC_SCALAR);CHKERRQ(ierr);
1121aabbc4fbSShri Abhyankar     /* now flip the values and store them in the matrix*/
1122aabbc4fbSShri Abhyankar     for (j=0; j<N; j++) {
1123aabbc4fbSShri Abhyankar       for (i=0; i<M; i++) {
1124aabbc4fbSShri Abhyankar         *v++ =w[i*N+j];
1125aabbc4fbSShri Abhyankar       }
1126aabbc4fbSShri Abhyankar     }
1127aabbc4fbSShri Abhyankar     ierr = PetscFree(w);CHKERRQ(ierr);
1128aabbc4fbSShri Abhyankar   } else {
1129aabbc4fbSShri Abhyankar     /* read row lengths */
1130854ce69bSBarry Smith     ierr = PetscMalloc1(M+1,&rowlengths);CHKERRQ(ierr);
1131aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
1132aabbc4fbSShri Abhyankar 
1133aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
1134aabbc4fbSShri Abhyankar     v = a->v;
1135aabbc4fbSShri Abhyankar 
1136aabbc4fbSShri Abhyankar     /* read column indices and nonzeros */
1137854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&scols);CHKERRQ(ierr);
1138aabbc4fbSShri Abhyankar     cols = scols;
1139aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT);CHKERRQ(ierr);
1140854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&svals);CHKERRQ(ierr);
1141aabbc4fbSShri Abhyankar     vals = svals;
1142aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR);CHKERRQ(ierr);
1143aabbc4fbSShri Abhyankar 
1144aabbc4fbSShri Abhyankar     /* insert into matrix */
1145aabbc4fbSShri Abhyankar     for (i=0; i<M; i++) {
1146aabbc4fbSShri Abhyankar       for (j=0; j<rowlengths[i]; j++) v[i+M*scols[j]] = svals[j];
1147aabbc4fbSShri Abhyankar       svals += rowlengths[i]; scols += rowlengths[i];
1148aabbc4fbSShri Abhyankar     }
1149aabbc4fbSShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1150aabbc4fbSShri Abhyankar     ierr = PetscFree(cols);CHKERRQ(ierr);
1151aabbc4fbSShri Abhyankar     ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1152aabbc4fbSShri Abhyankar   }
1153aabbc4fbSShri Abhyankar   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1154aabbc4fbSShri Abhyankar   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1155aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1156aabbc4fbSShri Abhyankar }
1157aabbc4fbSShri Abhyankar 
11586849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1159289bc588SBarry Smith {
1160932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1161dfbe8321SBarry Smith   PetscErrorCode    ierr;
116213f74950SBarry Smith   PetscInt          i,j;
11632dcb1b2aSMatthew Knepley   const char        *name;
116487828ca2SBarry Smith   PetscScalar       *v;
1165f3ef73ceSBarry Smith   PetscViewerFormat format;
11665f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1167ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
11685f481a85SSatish Balay #endif
1169932b0c3eSLois Curfman McInnes 
11703a40ed3dSBarry Smith   PetscFunctionBegin;
1171b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1172456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
11733a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1174fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1175d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1176d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
117744cd7ae7SLois Curfman McInnes       v    = a->v + i;
117877431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1179d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1180aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1181329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
118257622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1183329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
118457622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
11856831982aSBarry Smith         }
118680cd9d93SLois Curfman McInnes #else
11876831982aSBarry Smith         if (*v) {
118857622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
11896831982aSBarry Smith         }
119080cd9d93SLois Curfman McInnes #endif
11911b807ce4Svictorle         v += a->lda;
119280cd9d93SLois Curfman McInnes       }
1193b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
119480cd9d93SLois Curfman McInnes     }
1195d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
11963a40ed3dSBarry Smith   } else {
1197d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1198aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
119947989497SBarry Smith     /* determine if matrix has all real values */
120047989497SBarry Smith     v = a->v;
1201d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1202ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
120347989497SBarry Smith     }
120447989497SBarry Smith #endif
1205fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
12063a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1207d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1208d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1209fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1210ffac6cdbSBarry Smith     }
1211ffac6cdbSBarry Smith 
1212d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1213932b0c3eSLois Curfman McInnes       v = a->v + i;
1214d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1215aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
121647989497SBarry Smith         if (allreal) {
1217c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
121847989497SBarry Smith         } else {
1219c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
122047989497SBarry Smith         }
1221289bc588SBarry Smith #else
1222c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1223289bc588SBarry Smith #endif
12241b807ce4Svictorle         v += a->lda;
1225289bc588SBarry Smith       }
1226b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1227289bc588SBarry Smith     }
1228fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1229b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1230ffac6cdbSBarry Smith     }
1231d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1232da3a660dSBarry Smith   }
1233b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
12343a40ed3dSBarry Smith   PetscFunctionReturn(0);
1235289bc588SBarry Smith }
1236289bc588SBarry Smith 
12376849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_Binary(Mat A,PetscViewer viewer)
1238932b0c3eSLois Curfman McInnes {
1239932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
12406849ba73SBarry Smith   PetscErrorCode    ierr;
124113f74950SBarry Smith   int               fd;
1242d0f46423SBarry Smith   PetscInt          ict,j,n = A->cmap->n,m = A->rmap->n,i,*col_lens,nz = m*n;
1243f4403165SShri Abhyankar   PetscScalar       *v,*anonz,*vals;
1244f4403165SShri Abhyankar   PetscViewerFormat format;
1245932b0c3eSLois Curfman McInnes 
12463a40ed3dSBarry Smith   PetscFunctionBegin;
1247b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
124890ace30eSBarry Smith 
1249f4403165SShri Abhyankar   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1250f4403165SShri Abhyankar   if (format == PETSC_VIEWER_NATIVE) {
1251f4403165SShri Abhyankar     /* store the matrix as a dense matrix */
1252785e854fSJed Brown     ierr = PetscMalloc1(4,&col_lens);CHKERRQ(ierr);
12532205254eSKarl Rupp 
1254f4403165SShri Abhyankar     col_lens[0] = MAT_FILE_CLASSID;
1255f4403165SShri Abhyankar     col_lens[1] = m;
1256f4403165SShri Abhyankar     col_lens[2] = n;
1257f4403165SShri Abhyankar     col_lens[3] = MATRIX_BINARY_FORMAT_DENSE;
12582205254eSKarl Rupp 
1259f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,col_lens,4,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1260f4403165SShri Abhyankar     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1261f4403165SShri Abhyankar 
1262f4403165SShri Abhyankar     /* write out matrix, by rows */
1263854ce69bSBarry Smith     ierr = PetscMalloc1(m*n+1,&vals);CHKERRQ(ierr);
1264f4403165SShri Abhyankar     v    = a->v;
1265f4403165SShri Abhyankar     for (j=0; j<n; j++) {
1266f4403165SShri Abhyankar       for (i=0; i<m; i++) {
1267f4403165SShri Abhyankar         vals[j + i*n] = *v++;
1268f4403165SShri Abhyankar       }
1269f4403165SShri Abhyankar     }
1270f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,vals,n*m,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1271f4403165SShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1272f4403165SShri Abhyankar   } else {
1273854ce69bSBarry Smith     ierr = PetscMalloc1(4+nz,&col_lens);CHKERRQ(ierr);
12742205254eSKarl Rupp 
12750700a824SBarry Smith     col_lens[0] = MAT_FILE_CLASSID;
1276932b0c3eSLois Curfman McInnes     col_lens[1] = m;
1277932b0c3eSLois Curfman McInnes     col_lens[2] = n;
1278932b0c3eSLois Curfman McInnes     col_lens[3] = nz;
1279932b0c3eSLois Curfman McInnes 
1280932b0c3eSLois Curfman McInnes     /* store lengths of each row and write (including header) to file */
1281932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) col_lens[4+i] = n;
12826f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,4+m,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1283932b0c3eSLois Curfman McInnes 
1284932b0c3eSLois Curfman McInnes     /* Possibly should write in smaller increments, not whole matrix at once? */
1285932b0c3eSLois Curfman McInnes     /* store column indices (zero start index) */
1286932b0c3eSLois Curfman McInnes     ict = 0;
1287932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1288932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) col_lens[ict++] = j;
1289932b0c3eSLois Curfman McInnes     }
12906f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
1291606d414cSSatish Balay     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1292932b0c3eSLois Curfman McInnes 
1293932b0c3eSLois Curfman McInnes     /* store nonzero values */
1294854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&anonz);CHKERRQ(ierr);
1295932b0c3eSLois Curfman McInnes     ict  = 0;
1296932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1297932b0c3eSLois Curfman McInnes       v = a->v + i;
1298932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) {
12991b807ce4Svictorle         anonz[ict++] = *v; v += a->lda;
1300932b0c3eSLois Curfman McInnes       }
1301932b0c3eSLois Curfman McInnes     }
13026f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,anonz,nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1303606d414cSSatish Balay     ierr = PetscFree(anonz);CHKERRQ(ierr);
1304f4403165SShri Abhyankar   }
13053a40ed3dSBarry Smith   PetscFunctionReturn(0);
1306932b0c3eSLois Curfman McInnes }
1307932b0c3eSLois Curfman McInnes 
13089804daf3SBarry Smith #include <petscdraw.h>
1309e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1310f1af5d2fSBarry Smith {
1311f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
1312f1af5d2fSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
13136849ba73SBarry Smith   PetscErrorCode    ierr;
1314383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1315383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
131687828ca2SBarry Smith   PetscScalar       *v = a->v;
1317b0a32e0cSBarry Smith   PetscViewer       viewer;
1318b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1319f3ef73ceSBarry Smith   PetscViewerFormat format;
1320f1af5d2fSBarry Smith 
1321f1af5d2fSBarry Smith   PetscFunctionBegin;
1322f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1323b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1324b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1325f1af5d2fSBarry Smith 
1326f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1327383922c3SLisandro Dalcin 
1328fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1329383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1330f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1331f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1332383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1333f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1334f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1335f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1336329f5518SBarry Smith         if (PetscRealPart(v[j*m+i]) >  0.) {
1337b0a32e0cSBarry Smith           color = PETSC_DRAW_RED;
1338329f5518SBarry Smith         } else if (PetscRealPart(v[j*m+i]) <  0.) {
1339b0a32e0cSBarry Smith           color = PETSC_DRAW_BLUE;
1340f1af5d2fSBarry Smith         } else {
1341f1af5d2fSBarry Smith           continue;
1342f1af5d2fSBarry Smith         }
1343b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1344f1af5d2fSBarry Smith       }
1345f1af5d2fSBarry Smith     }
1346383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1347f1af5d2fSBarry Smith   } else {
1348f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1349f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1350b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1351b05fc000SLisandro Dalcin     PetscDraw popup;
1352b05fc000SLisandro Dalcin 
1353f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1354f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1355f1af5d2fSBarry Smith     }
1356383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1357b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
135845f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1359383922c3SLisandro Dalcin 
1360383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1361f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1362f1af5d2fSBarry Smith       x_l = j;
1363f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1364f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1365f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1366f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1367b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1368b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1369f1af5d2fSBarry Smith       }
1370f1af5d2fSBarry Smith     }
1371383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1372f1af5d2fSBarry Smith   }
1373f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1374f1af5d2fSBarry Smith }
1375f1af5d2fSBarry Smith 
1376e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1377f1af5d2fSBarry Smith {
1378b0a32e0cSBarry Smith   PetscDraw      draw;
1379ace3abfcSBarry Smith   PetscBool      isnull;
1380329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1381dfbe8321SBarry Smith   PetscErrorCode ierr;
1382f1af5d2fSBarry Smith 
1383f1af5d2fSBarry Smith   PetscFunctionBegin;
1384b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1385b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1386abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1387f1af5d2fSBarry Smith 
1388d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1389f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1390b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1391832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1392b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
13930298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1394832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1395f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1396f1af5d2fSBarry Smith }
1397f1af5d2fSBarry Smith 
1398dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1399932b0c3eSLois Curfman McInnes {
1400dfbe8321SBarry Smith   PetscErrorCode ierr;
1401ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1402932b0c3eSLois Curfman McInnes 
14033a40ed3dSBarry Smith   PetscFunctionBegin;
1404251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1405251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1406251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
14070f5bd95cSBarry Smith 
1408c45a1595SBarry Smith   if (iascii) {
1409c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
14100f5bd95cSBarry Smith   } else if (isbinary) {
14113a40ed3dSBarry Smith     ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr);
1412f1af5d2fSBarry Smith   } else if (isdraw) {
1413f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1414932b0c3eSLois Curfman McInnes   }
14153a40ed3dSBarry Smith   PetscFunctionReturn(0);
1416932b0c3eSLois Curfman McInnes }
1417289bc588SBarry Smith 
1418d3042a70SBarry Smith static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar array[])
1419d3042a70SBarry Smith {
1420d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1421d3042a70SBarry Smith 
1422d3042a70SBarry Smith   PetscFunctionBegin;
1423d3042a70SBarry Smith   a->unplacedarray       = a->v;
1424d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1425d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1426d3042a70SBarry Smith   PetscFunctionReturn(0);
1427d3042a70SBarry Smith }
1428d3042a70SBarry Smith 
1429d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1430d3042a70SBarry Smith {
1431d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1432d3042a70SBarry Smith 
1433d3042a70SBarry Smith   PetscFunctionBegin;
1434d3042a70SBarry Smith   a->v             = a->unplacedarray;
1435d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1436d3042a70SBarry Smith   a->unplacedarray = NULL;
1437d3042a70SBarry Smith   PetscFunctionReturn(0);
1438d3042a70SBarry Smith }
1439d3042a70SBarry Smith 
1440e0877f53SBarry Smith static PetscErrorCode MatDestroy_SeqDense(Mat mat)
1441289bc588SBarry Smith {
1442ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1443dfbe8321SBarry Smith   PetscErrorCode ierr;
144490f02eecSBarry Smith 
14453a40ed3dSBarry Smith   PetscFunctionBegin;
1446aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1447d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1448a5a9c739SBarry Smith #endif
144905b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1450a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1451abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
14526857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1453bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1454dbd8c25aSHong Zhang 
1455dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
1456bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
1457d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1458d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
1459bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
14608baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
14618baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
14628baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
14638baccfbdSHong Zhang #endif
1464bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
1465bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1466bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1467bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1468abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatPtAP_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14693bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14703bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14713bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
147286aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
147386aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
14743a40ed3dSBarry Smith   PetscFunctionReturn(0);
1475289bc588SBarry Smith }
1476289bc588SBarry Smith 
1477e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1478289bc588SBarry Smith {
1479c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
14806849ba73SBarry Smith   PetscErrorCode ierr;
148113f74950SBarry Smith   PetscInt       k,j,m,n,M;
148287828ca2SBarry Smith   PetscScalar    *v,tmp;
148348b35521SBarry Smith 
14843a40ed3dSBarry Smith   PetscFunctionBegin;
1485d0f46423SBarry Smith   v = mat->v; m = A->rmap->n; M = mat->lda; n = A->cmap->n;
14862847e3fdSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX && m == n) { /* in place transpose */
1487d3e5ee88SLois Curfman McInnes     for (j=0; j<m; j++) {
1488289bc588SBarry Smith       for (k=0; k<j; k++) {
14891b807ce4Svictorle         tmp        = v[j + k*M];
14901b807ce4Svictorle         v[j + k*M] = v[k + j*M];
14911b807ce4Svictorle         v[k + j*M] = tmp;
1492289bc588SBarry Smith       }
1493289bc588SBarry Smith     }
14943a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1495d3e5ee88SLois Curfman McInnes     Mat          tmat;
1496ec8511deSBarry Smith     Mat_SeqDense *tmatd;
149787828ca2SBarry Smith     PetscScalar  *v2;
1498af36a384SStefano Zampini     PetscInt     M2;
1499ea709b57SSatish Balay 
15002847e3fdSStefano Zampini     if (reuse != MAT_REUSE_MATRIX) {
1501ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1502d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
15037adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
15040298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1505fc4dec0aSBarry Smith     } else {
1506fc4dec0aSBarry Smith       tmat = *matout;
1507fc4dec0aSBarry Smith     }
1508ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1509af36a384SStefano Zampini     v = mat->v; v2 = tmatd->v; M2 = tmatd->lda;
1510d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1511af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1512d3e5ee88SLois Curfman McInnes     }
15136d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15146d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15152847e3fdSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) *matout = tmat;
15162847e3fdSStefano Zampini     else {
15172847e3fdSStefano Zampini       ierr = MatHeaderMerge(A,&tmat);CHKERRQ(ierr);
15182847e3fdSStefano Zampini     }
151948b35521SBarry Smith   }
15203a40ed3dSBarry Smith   PetscFunctionReturn(0);
1521289bc588SBarry Smith }
1522289bc588SBarry Smith 
1523e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1524289bc588SBarry Smith {
1525c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat1 = (Mat_SeqDense*)A1->data;
1526c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat2 = (Mat_SeqDense*)A2->data;
152713f74950SBarry Smith   PetscInt     i,j;
1528a2ea699eSBarry Smith   PetscScalar  *v1,*v2;
15299ea5d5aeSSatish Balay 
15303a40ed3dSBarry Smith   PetscFunctionBegin;
1531d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1532d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1533d0f46423SBarry Smith   for (i=0; i<A1->rmap->n; i++) {
15341b807ce4Svictorle     v1 = mat1->v+i; v2 = mat2->v+i;
1535d0f46423SBarry Smith     for (j=0; j<A1->cmap->n; j++) {
15363a40ed3dSBarry Smith       if (*v1 != *v2) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
15371b807ce4Svictorle       v1 += mat1->lda; v2 += mat2->lda;
15381b807ce4Svictorle     }
1539289bc588SBarry Smith   }
154077c4ece6SBarry Smith   *flg = PETSC_TRUE;
15413a40ed3dSBarry Smith   PetscFunctionReturn(0);
1542289bc588SBarry Smith }
1543289bc588SBarry Smith 
1544e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1545289bc588SBarry Smith {
1546c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
1547dfbe8321SBarry Smith   PetscErrorCode ierr;
154813f74950SBarry Smith   PetscInt       i,n,len;
154987828ca2SBarry Smith   PetscScalar    *x,zero = 0.0;
155044cd7ae7SLois Curfman McInnes 
15513a40ed3dSBarry Smith   PetscFunctionBegin;
15522dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
15537a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
15541ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1555d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1556e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
155744cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
15581b807ce4Svictorle     x[i] = mat->v[i*mat->lda + i];
1559289bc588SBarry Smith   }
15601ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
15613a40ed3dSBarry Smith   PetscFunctionReturn(0);
1562289bc588SBarry Smith }
1563289bc588SBarry Smith 
1564e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1565289bc588SBarry Smith {
1566c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1567f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1568f1ceaac6SMatthew G. Knepley   PetscScalar       x,*v;
1569dfbe8321SBarry Smith   PetscErrorCode    ierr;
1570d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
157155659b69SBarry Smith 
15723a40ed3dSBarry Smith   PetscFunctionBegin;
157328988994SBarry Smith   if (ll) {
15747a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1575f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1576e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1577da3a660dSBarry Smith     for (i=0; i<m; i++) {
1578da3a660dSBarry Smith       x = l[i];
1579da3a660dSBarry Smith       v = mat->v + i;
1580b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1581da3a660dSBarry Smith     }
1582f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1583eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1584da3a660dSBarry Smith   }
158528988994SBarry Smith   if (rr) {
15867a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1587f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1588e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1589da3a660dSBarry Smith     for (i=0; i<n; i++) {
1590da3a660dSBarry Smith       x = r[i];
1591b43bac26SStefano Zampini       v = mat->v + i*mat->lda;
15922205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1593da3a660dSBarry Smith     }
1594f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1595eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1596da3a660dSBarry Smith   }
15973a40ed3dSBarry Smith   PetscFunctionReturn(0);
1598289bc588SBarry Smith }
1599289bc588SBarry Smith 
1600e0877f53SBarry Smith static PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1601289bc588SBarry Smith {
1602c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
160387828ca2SBarry Smith   PetscScalar    *v   = mat->v;
1604329f5518SBarry Smith   PetscReal      sum  = 0.0;
1605d0f46423SBarry Smith   PetscInt       lda  =mat->lda,m=A->rmap->n,i,j;
1606efee365bSSatish Balay   PetscErrorCode ierr;
160755659b69SBarry Smith 
16083a40ed3dSBarry Smith   PetscFunctionBegin;
1609289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1610a5ce6ee0Svictorle     if (lda>m) {
1611d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1612a5ce6ee0Svictorle         v = mat->v+j*lda;
1613a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1614a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1615a5ce6ee0Svictorle         }
1616a5ce6ee0Svictorle       }
1617a5ce6ee0Svictorle     } else {
1618570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1619570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1620570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1621570b7f6dSBarry Smith     }
1622570b7f6dSBarry Smith #else
1623d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1624329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1625289bc588SBarry Smith       }
1626a5ce6ee0Svictorle     }
16278f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1628570b7f6dSBarry Smith #endif
1629dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16303a40ed3dSBarry Smith   } else if (type == NORM_1) {
1631064f8208SBarry Smith     *nrm = 0.0;
1632d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
16331b807ce4Svictorle       v   = mat->v + j*mat->lda;
1634289bc588SBarry Smith       sum = 0.0;
1635d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
163633a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1637289bc588SBarry Smith       }
1638064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1639289bc588SBarry Smith     }
1640eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16413a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1642064f8208SBarry Smith     *nrm = 0.0;
1643d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1644289bc588SBarry Smith       v   = mat->v + j;
1645289bc588SBarry Smith       sum = 0.0;
1646d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
16471b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1648289bc588SBarry Smith       }
1649064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1650289bc588SBarry Smith     }
1651eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1652e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
16533a40ed3dSBarry Smith   PetscFunctionReturn(0);
1654289bc588SBarry Smith }
1655289bc588SBarry Smith 
1656e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1657289bc588SBarry Smith {
1658c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
165963ba0a88SBarry Smith   PetscErrorCode ierr;
166067e560aaSBarry Smith 
16613a40ed3dSBarry Smith   PetscFunctionBegin;
1662b5a2b587SKris Buschelman   switch (op) {
1663b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
16644e0d8c25SBarry Smith     aij->roworiented = flg;
1665b5a2b587SKris Buschelman     break;
1666512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1667b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
16683971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
16694e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
167013fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1671b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1672b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
16730f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
16745021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
16755021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
16765021d80fSJed Brown     break;
16775021d80fSJed Brown   case MAT_SPD:
167877e54ba9SKris Buschelman   case MAT_SYMMETRIC:
167977e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
16809a4540c5SBarry Smith   case MAT_HERMITIAN:
16819a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
16825021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
168377e54ba9SKris Buschelman     break;
1684b5a2b587SKris Buschelman   default:
1685e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
16863a40ed3dSBarry Smith   }
16873a40ed3dSBarry Smith   PetscFunctionReturn(0);
1688289bc588SBarry Smith }
1689289bc588SBarry Smith 
1690e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
16916f0a148fSBarry Smith {
1692ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
16936849ba73SBarry Smith   PetscErrorCode ierr;
1694d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
16953a40ed3dSBarry Smith 
16963a40ed3dSBarry Smith   PetscFunctionBegin;
1697a5ce6ee0Svictorle   if (lda>m) {
1698d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1699a5ce6ee0Svictorle       ierr = PetscMemzero(l->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr);
1700a5ce6ee0Svictorle     }
1701a5ce6ee0Svictorle   } else {
1702d0f46423SBarry Smith     ierr = PetscMemzero(l->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
1703a5ce6ee0Svictorle   }
17043a40ed3dSBarry Smith   PetscFunctionReturn(0);
17056f0a148fSBarry Smith }
17066f0a148fSBarry Smith 
1707e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
17086f0a148fSBarry Smith {
170997b48c8fSBarry Smith   PetscErrorCode    ierr;
1710ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1711b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
171297b48c8fSBarry Smith   PetscScalar       *slot,*bb;
171397b48c8fSBarry Smith   const PetscScalar *xx;
171455659b69SBarry Smith 
17153a40ed3dSBarry Smith   PetscFunctionBegin;
1716b9679d65SBarry Smith #if defined(PETSC_USE_DEBUG)
1717b9679d65SBarry Smith   for (i=0; i<N; i++) {
1718b9679d65SBarry Smith     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1719b9679d65SBarry 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);
1720b9679d65SBarry Smith   }
1721b9679d65SBarry Smith #endif
1722b9679d65SBarry Smith 
172397b48c8fSBarry Smith   /* fix right hand side if needed */
172497b48c8fSBarry Smith   if (x && b) {
172597b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
172697b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
17272205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
172897b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
172997b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
173097b48c8fSBarry Smith   }
173197b48c8fSBarry Smith 
17326f0a148fSBarry Smith   for (i=0; i<N; i++) {
17336f0a148fSBarry Smith     slot = l->v + rows[i];
1734b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
17356f0a148fSBarry Smith   }
1736f4df32b1SMatthew Knepley   if (diag != 0.0) {
1737b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
17386f0a148fSBarry Smith     for (i=0; i<N; i++) {
1739b9679d65SBarry Smith       slot  = l->v + (m+1)*rows[i];
1740f4df32b1SMatthew Knepley       *slot = diag;
17416f0a148fSBarry Smith     }
17426f0a148fSBarry Smith   }
17433a40ed3dSBarry Smith   PetscFunctionReturn(0);
17446f0a148fSBarry Smith }
1745557bce09SLois Curfman McInnes 
1746e0877f53SBarry Smith static PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar *array[])
174764e87e97SBarry Smith {
1748c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
17493a40ed3dSBarry Smith 
17503a40ed3dSBarry Smith   PetscFunctionBegin;
1751e32f2f54SBarry 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");
175264e87e97SBarry Smith   *array = mat->v;
17533a40ed3dSBarry Smith   PetscFunctionReturn(0);
175464e87e97SBarry Smith }
17550754003eSLois Curfman McInnes 
1756e0877f53SBarry Smith static PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar *array[])
1757ff14e315SSatish Balay {
17583a40ed3dSBarry Smith   PetscFunctionBegin;
17593a40ed3dSBarry Smith   PetscFunctionReturn(0);
1760ff14e315SSatish Balay }
17610754003eSLois Curfman McInnes 
1762dec5eb66SMatthew G Knepley /*@C
17638c778c55SBarry Smith    MatDenseGetArray - gives access to the array where the data for a SeqDense matrix is stored
176473a71a0fSBarry Smith 
17658572280aSBarry Smith    Logically Collective on Mat
176673a71a0fSBarry Smith 
176773a71a0fSBarry Smith    Input Parameter:
1768579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
176973a71a0fSBarry Smith 
177073a71a0fSBarry Smith    Output Parameter:
177173a71a0fSBarry Smith .   array - pointer to the data
177273a71a0fSBarry Smith 
177373a71a0fSBarry Smith    Level: intermediate
177473a71a0fSBarry Smith 
17758572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
177673a71a0fSBarry Smith @*/
17778c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
177873a71a0fSBarry Smith {
177973a71a0fSBarry Smith   PetscErrorCode ierr;
178073a71a0fSBarry Smith 
178173a71a0fSBarry Smith   PetscFunctionBegin;
17828c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
178373a71a0fSBarry Smith   PetscFunctionReturn(0);
178473a71a0fSBarry Smith }
178573a71a0fSBarry Smith 
1786dec5eb66SMatthew G Knepley /*@C
1787579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
178873a71a0fSBarry Smith 
17898572280aSBarry Smith    Logically Collective on Mat
17908572280aSBarry Smith 
17918572280aSBarry Smith    Input Parameters:
17928572280aSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
17938572280aSBarry Smith .  array - pointer to the data
17948572280aSBarry Smith 
17958572280aSBarry Smith    Level: intermediate
17968572280aSBarry Smith 
17978572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
17988572280aSBarry Smith @*/
17998572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
18008572280aSBarry Smith {
18018572280aSBarry Smith   PetscErrorCode ierr;
18028572280aSBarry Smith 
18038572280aSBarry Smith   PetscFunctionBegin;
18048572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
18058572280aSBarry Smith   if (array) *array = NULL;
18068572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
18078572280aSBarry Smith   PetscFunctionReturn(0);
18088572280aSBarry Smith }
18098572280aSBarry Smith 
18108572280aSBarry Smith /*@C
18118572280aSBarry Smith    MatDenseGetArrayRead - gives access to the array where the data for a SeqDense matrix is stored
18128572280aSBarry Smith 
18138572280aSBarry Smith    Not Collective
18148572280aSBarry Smith 
18158572280aSBarry Smith    Input Parameter:
18168572280aSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
18178572280aSBarry Smith 
18188572280aSBarry Smith    Output Parameter:
18198572280aSBarry Smith .   array - pointer to the data
18208572280aSBarry Smith 
18218572280aSBarry Smith    Level: intermediate
18228572280aSBarry Smith 
18238572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArray(), MatDenseRestoreArrayRead()
18248572280aSBarry Smith @*/
18258572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
18268572280aSBarry Smith {
18278572280aSBarry Smith   PetscErrorCode ierr;
18288572280aSBarry Smith 
18298572280aSBarry Smith   PetscFunctionBegin;
18308572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
18318572280aSBarry Smith   PetscFunctionReturn(0);
18328572280aSBarry Smith }
18338572280aSBarry Smith 
18348572280aSBarry Smith /*@C
18358572280aSBarry Smith    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
18368572280aSBarry Smith 
183773a71a0fSBarry Smith    Not Collective
183873a71a0fSBarry Smith 
183973a71a0fSBarry Smith    Input Parameters:
1840579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
184173a71a0fSBarry Smith .  array - pointer to the data
184273a71a0fSBarry Smith 
184373a71a0fSBarry Smith    Level: intermediate
184473a71a0fSBarry Smith 
18458572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArray()
184673a71a0fSBarry Smith @*/
18478572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
184873a71a0fSBarry Smith {
184973a71a0fSBarry Smith   PetscErrorCode ierr;
185073a71a0fSBarry Smith 
185173a71a0fSBarry Smith   PetscFunctionBegin;
18528572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
18538572280aSBarry Smith   if (array) *array = NULL;
185473a71a0fSBarry Smith   PetscFunctionReturn(0);
185573a71a0fSBarry Smith }
185673a71a0fSBarry Smith 
18577dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
18580754003eSLois Curfman McInnes {
1859c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
18606849ba73SBarry Smith   PetscErrorCode ierr;
18615d0c19d7SBarry Smith   PetscInt       i,j,nrows,ncols;
18625d0c19d7SBarry Smith   const PetscInt *irow,*icol;
186387828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
18640754003eSLois Curfman McInnes   Mat            newmat;
18650754003eSLois Curfman McInnes 
18663a40ed3dSBarry Smith   PetscFunctionBegin;
186778b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
186878b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1869e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1870e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
18710754003eSLois Curfman McInnes 
1872182d2002SSatish Balay   /* Check submatrixcall */
1873182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
187413f74950SBarry Smith     PetscInt n_cols,n_rows;
1875182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
187621a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
1877f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
1878c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
187921a2c019SBarry Smith     }
1880182d2002SSatish Balay     newmat = *B;
1881182d2002SSatish Balay   } else {
18820754003eSLois Curfman McInnes     /* Create and fill new matrix */
1883ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
1884f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
18857adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
18860298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1887182d2002SSatish Balay   }
1888182d2002SSatish Balay 
1889182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1890182d2002SSatish Balay   bv = ((Mat_SeqDense*)newmat->data)->v;
1891182d2002SSatish Balay 
1892182d2002SSatish Balay   for (i=0; i<ncols; i++) {
18936de62eeeSBarry Smith     av = v + mat->lda*icol[i];
18942205254eSKarl Rupp     for (j=0; j<nrows; j++) *bv++ = av[irow[j]];
18950754003eSLois Curfman McInnes   }
1896182d2002SSatish Balay 
1897182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
18986d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18996d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19000754003eSLois Curfman McInnes 
19010754003eSLois Curfman McInnes   /* Free work space */
190278b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
190378b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1904182d2002SSatish Balay   *B   = newmat;
19053a40ed3dSBarry Smith   PetscFunctionReturn(0);
19060754003eSLois Curfman McInnes }
19070754003eSLois Curfman McInnes 
19087dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1909905e6a2fSBarry Smith {
19106849ba73SBarry Smith   PetscErrorCode ierr;
191113f74950SBarry Smith   PetscInt       i;
1912905e6a2fSBarry Smith 
19133a40ed3dSBarry Smith   PetscFunctionBegin;
1914905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1915df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
1916905e6a2fSBarry Smith   }
1917905e6a2fSBarry Smith 
1918905e6a2fSBarry Smith   for (i=0; i<n; i++) {
19197dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1920905e6a2fSBarry Smith   }
19213a40ed3dSBarry Smith   PetscFunctionReturn(0);
1922905e6a2fSBarry Smith }
1923905e6a2fSBarry Smith 
1924e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
1925c0aa2d19SHong Zhang {
1926c0aa2d19SHong Zhang   PetscFunctionBegin;
1927c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1928c0aa2d19SHong Zhang }
1929c0aa2d19SHong Zhang 
1930e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
1931c0aa2d19SHong Zhang {
1932c0aa2d19SHong Zhang   PetscFunctionBegin;
1933c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1934c0aa2d19SHong Zhang }
1935c0aa2d19SHong Zhang 
1936e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
19374b0e389bSBarry Smith {
19384b0e389bSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
19396849ba73SBarry Smith   PetscErrorCode ierr;
1940d0f46423SBarry Smith   PetscInt       lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
19413a40ed3dSBarry Smith 
19423a40ed3dSBarry Smith   PetscFunctionBegin;
194333f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
194433f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
1945cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
19463a40ed3dSBarry Smith     PetscFunctionReturn(0);
19473a40ed3dSBarry Smith   }
1948e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
1949a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
19500dbb7854Svictorle     for (j=0; j<n; j++) {
1951a5ce6ee0Svictorle       ierr = PetscMemcpy(b->v+j*lda2,a->v+j*lda1,m*sizeof(PetscScalar));CHKERRQ(ierr);
1952a5ce6ee0Svictorle     }
1953a5ce6ee0Svictorle   } else {
1954d0f46423SBarry Smith     ierr = PetscMemcpy(b->v,a->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
1955a5ce6ee0Svictorle   }
1956cdc753b6SBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
1957273d9f13SBarry Smith   PetscFunctionReturn(0);
1958273d9f13SBarry Smith }
1959273d9f13SBarry Smith 
1960e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
1961273d9f13SBarry Smith {
1962dfbe8321SBarry Smith   PetscErrorCode ierr;
1963273d9f13SBarry Smith 
1964273d9f13SBarry Smith   PetscFunctionBegin;
1965273d9f13SBarry Smith   ierr =  MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
19663a40ed3dSBarry Smith   PetscFunctionReturn(0);
19674b0e389bSBarry Smith }
19684b0e389bSBarry Smith 
1969ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
1970ba337c44SJed Brown {
1971ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1972ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1973ba337c44SJed Brown   PetscScalar  *aa = a->v;
1974ba337c44SJed Brown 
1975ba337c44SJed Brown   PetscFunctionBegin;
1976ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
1977ba337c44SJed Brown   PetscFunctionReturn(0);
1978ba337c44SJed Brown }
1979ba337c44SJed Brown 
1980ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
1981ba337c44SJed Brown {
1982ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1983ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1984ba337c44SJed Brown   PetscScalar  *aa = a->v;
1985ba337c44SJed Brown 
1986ba337c44SJed Brown   PetscFunctionBegin;
1987ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
1988ba337c44SJed Brown   PetscFunctionReturn(0);
1989ba337c44SJed Brown }
1990ba337c44SJed Brown 
1991ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
1992ba337c44SJed Brown {
1993ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1994ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
1995ba337c44SJed Brown   PetscScalar  *aa = a->v;
1996ba337c44SJed Brown 
1997ba337c44SJed Brown   PetscFunctionBegin;
1998ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
1999ba337c44SJed Brown   PetscFunctionReturn(0);
2000ba337c44SJed Brown }
2001284134d9SBarry Smith 
2002a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
2003150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
2004a9fe9ddaSSatish Balay {
2005a9fe9ddaSSatish Balay   PetscErrorCode ierr;
2006a9fe9ddaSSatish Balay 
2007a9fe9ddaSSatish Balay   PetscFunctionBegin;
2008a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
20093ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2010a9fe9ddaSSatish Balay     ierr = MatMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
20113ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2012a9fe9ddaSSatish Balay   }
20133ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2014a9fe9ddaSSatish Balay   ierr = MatMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
20153ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2016a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2017a9fe9ddaSSatish Balay }
2018a9fe9ddaSSatish Balay 
2019a9fe9ddaSSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
2020a9fe9ddaSSatish Balay {
2021ee16a9a1SHong Zhang   PetscErrorCode ierr;
2022d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
2023ee16a9a1SHong Zhang   Mat            Cmat;
2024a9fe9ddaSSatish Balay 
2025ee16a9a1SHong Zhang   PetscFunctionBegin;
2026e32f2f54SBarry 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);
2027ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
2028ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
2029ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
20300298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
2031d73949e8SHong Zhang 
2032ee16a9a1SHong Zhang   *C = Cmat;
2033ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2034ee16a9a1SHong Zhang }
2035a9fe9ddaSSatish Balay 
2036a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2037a9fe9ddaSSatish Balay {
2038a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2039a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2040a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
20410805154bSBarry Smith   PetscBLASInt   m,n,k;
2042a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
2043c5df96a5SBarry Smith   PetscErrorCode ierr;
2044fd4e9aacSBarry Smith   PetscBool      flg;
2045a9fe9ddaSSatish Balay 
2046a9fe9ddaSSatish Balay   PetscFunctionBegin;
2047fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQDENSE,&flg);CHKERRQ(ierr);
2048fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Second matrix must be dense");
2049fd4e9aacSBarry Smith 
2050fd4e9aacSBarry Smith   /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/
2051fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
2052fd4e9aacSBarry Smith   if (flg) {
2053fd4e9aacSBarry Smith     C->ops->matmultnumeric = MatMatMultNumeric_SeqAIJ_SeqDense;
2054fd4e9aacSBarry Smith     ierr = (*C->ops->matmultnumeric)(A,B,C);CHKERRQ(ierr);
2055fd4e9aacSBarry Smith     PetscFunctionReturn(0);
2056fd4e9aacSBarry Smith   }
2057fd4e9aacSBarry Smith 
2058fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&flg);CHKERRQ(ierr);
2059fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"First matrix must be dense");
20608208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
20618208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2062c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
2063*49d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
20645ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2065a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2066a9fe9ddaSSatish Balay }
2067a9fe9ddaSSatish Balay 
206869f65d41SStefano Zampini PetscErrorCode MatMatTransposeMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
206969f65d41SStefano Zampini {
207069f65d41SStefano Zampini   PetscErrorCode ierr;
207169f65d41SStefano Zampini 
207269f65d41SStefano Zampini   PetscFunctionBegin;
207369f65d41SStefano Zampini   if (scall == MAT_INITIAL_MATRIX) {
207469f65d41SStefano Zampini     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
207569f65d41SStefano Zampini     ierr = MatMatTransposeMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
207669f65d41SStefano Zampini     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
207769f65d41SStefano Zampini   }
207869f65d41SStefano Zampini   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
207969f65d41SStefano Zampini   ierr = MatMatTransposeMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
208069f65d41SStefano Zampini   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
208169f65d41SStefano Zampini   PetscFunctionReturn(0);
208269f65d41SStefano Zampini }
208369f65d41SStefano Zampini 
208469f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
208569f65d41SStefano Zampini {
208669f65d41SStefano Zampini   PetscErrorCode ierr;
208769f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
208869f65d41SStefano Zampini   Mat            Cmat;
208969f65d41SStefano Zampini 
209069f65d41SStefano Zampini   PetscFunctionBegin;
209169f65d41SStefano 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);
209269f65d41SStefano Zampini   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
209369f65d41SStefano Zampini   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
209469f65d41SStefano Zampini   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
209569f65d41SStefano Zampini   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
209669f65d41SStefano Zampini 
209769f65d41SStefano Zampini   Cmat->assembled = PETSC_TRUE;
209869f65d41SStefano Zampini 
209969f65d41SStefano Zampini   *C = Cmat;
210069f65d41SStefano Zampini   PetscFunctionReturn(0);
210169f65d41SStefano Zampini }
210269f65d41SStefano Zampini 
210369f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
210469f65d41SStefano Zampini {
210569f65d41SStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
210669f65d41SStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
210769f65d41SStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
210869f65d41SStefano Zampini   PetscBLASInt   m,n,k;
210969f65d41SStefano Zampini   PetscScalar    _DOne=1.0,_DZero=0.0;
211069f65d41SStefano Zampini   PetscErrorCode ierr;
211169f65d41SStefano Zampini 
211269f65d41SStefano Zampini   PetscFunctionBegin;
2113*49d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
2114*49d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
211569f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
2116*49d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
211769f65d41SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
211869f65d41SStefano Zampini   PetscFunctionReturn(0);
211969f65d41SStefano Zampini }
212069f65d41SStefano Zampini 
212175648e8dSHong Zhang PetscErrorCode MatTransposeMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
2122a9fe9ddaSSatish Balay {
2123a9fe9ddaSSatish Balay   PetscErrorCode ierr;
2124a9fe9ddaSSatish Balay 
2125a9fe9ddaSSatish Balay   PetscFunctionBegin;
2126a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
21273ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
212875648e8dSHong Zhang     ierr = MatTransposeMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
21293ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2130a9fe9ddaSSatish Balay   }
21313ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
213275648e8dSHong Zhang   ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
21333ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2134a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2135a9fe9ddaSSatish Balay }
2136a9fe9ddaSSatish Balay 
213775648e8dSHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
2138a9fe9ddaSSatish Balay {
2139ee16a9a1SHong Zhang   PetscErrorCode ierr;
2140d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
2141ee16a9a1SHong Zhang   Mat            Cmat;
2142a9fe9ddaSSatish Balay 
2143ee16a9a1SHong Zhang   PetscFunctionBegin;
2144e32f2f54SBarry 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);
2145ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
2146ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
2147ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
21480298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
21492205254eSKarl Rupp 
2150ee16a9a1SHong Zhang   Cmat->assembled = PETSC_TRUE;
21512205254eSKarl Rupp 
2152ee16a9a1SHong Zhang   *C = Cmat;
2153ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2154ee16a9a1SHong Zhang }
2155a9fe9ddaSSatish Balay 
215675648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2157a9fe9ddaSSatish Balay {
2158a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2159a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2160a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
21610805154bSBarry Smith   PetscBLASInt   m,n,k;
2162a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
2163c5df96a5SBarry Smith   PetscErrorCode ierr;
2164a9fe9ddaSSatish Balay 
2165a9fe9ddaSSatish Balay   PetscFunctionBegin;
21668208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
21678208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2168c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
2169*49d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
21705ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2171a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2172a9fe9ddaSSatish Balay }
2173985db425SBarry Smith 
2174e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2175985db425SBarry Smith {
2176985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2177985db425SBarry Smith   PetscErrorCode ierr;
2178d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
2179985db425SBarry Smith   PetscScalar    *x;
2180985db425SBarry Smith   MatScalar      *aa = a->v;
2181985db425SBarry Smith 
2182985db425SBarry Smith   PetscFunctionBegin;
2183e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2184985db425SBarry Smith 
2185985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2186985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2187985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2188e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2189985db425SBarry Smith   for (i=0; i<m; i++) {
2190985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2191985db425SBarry Smith     for (j=1; j<n; j++) {
2192985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
2193985db425SBarry Smith     }
2194985db425SBarry Smith   }
2195985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2196985db425SBarry Smith   PetscFunctionReturn(0);
2197985db425SBarry Smith }
2198985db425SBarry Smith 
2199e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2200985db425SBarry Smith {
2201985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2202985db425SBarry Smith   PetscErrorCode ierr;
2203d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
2204985db425SBarry Smith   PetscScalar    *x;
2205985db425SBarry Smith   PetscReal      atmp;
2206985db425SBarry Smith   MatScalar      *aa = a->v;
2207985db425SBarry Smith 
2208985db425SBarry Smith   PetscFunctionBegin;
2209e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2210985db425SBarry Smith 
2211985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2212985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2213985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2214e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2215985db425SBarry Smith   for (i=0; i<m; i++) {
22169189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2217985db425SBarry Smith     for (j=1; j<n; j++) {
2218985db425SBarry Smith       atmp = PetscAbsScalar(aa[i+m*j]);
2219985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2220985db425SBarry Smith     }
2221985db425SBarry Smith   }
2222985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2223985db425SBarry Smith   PetscFunctionReturn(0);
2224985db425SBarry Smith }
2225985db425SBarry Smith 
2226e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2227985db425SBarry Smith {
2228985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2229985db425SBarry Smith   PetscErrorCode ierr;
2230d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
2231985db425SBarry Smith   PetscScalar    *x;
2232985db425SBarry Smith   MatScalar      *aa = a->v;
2233985db425SBarry Smith 
2234985db425SBarry Smith   PetscFunctionBegin;
2235e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2236985db425SBarry Smith 
2237985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2238985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2239985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2240e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2241985db425SBarry Smith   for (i=0; i<m; i++) {
2242985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2243985db425SBarry Smith     for (j=1; j<n; j++) {
2244985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
2245985db425SBarry Smith     }
2246985db425SBarry Smith   }
2247985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2248985db425SBarry Smith   PetscFunctionReturn(0);
2249985db425SBarry Smith }
2250985db425SBarry Smith 
2251e0877f53SBarry Smith static PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
22528d0534beSBarry Smith {
22538d0534beSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
22548d0534beSBarry Smith   PetscErrorCode ierr;
22558d0534beSBarry Smith   PetscScalar    *x;
22568d0534beSBarry Smith 
22578d0534beSBarry Smith   PetscFunctionBegin;
2258e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
22598d0534beSBarry Smith 
22608d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2261d0f46423SBarry Smith   ierr = PetscMemcpy(x,a->v+col*a->lda,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
22628d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
22638d0534beSBarry Smith   PetscFunctionReturn(0);
22648d0534beSBarry Smith }
22658d0534beSBarry Smith 
22660716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
22670716a85fSBarry Smith {
22680716a85fSBarry Smith   PetscErrorCode ierr;
22690716a85fSBarry Smith   PetscInt       i,j,m,n;
22700716a85fSBarry Smith   PetscScalar    *a;
22710716a85fSBarry Smith 
22720716a85fSBarry Smith   PetscFunctionBegin;
22730716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
22740716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
22758c778c55SBarry Smith   ierr = MatDenseGetArray(A,&a);CHKERRQ(ierr);
22760716a85fSBarry Smith   if (type == NORM_2) {
22770716a85fSBarry Smith     for (i=0; i<n; i++) {
22780716a85fSBarry Smith       for (j=0; j<m; j++) {
22790716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
22800716a85fSBarry Smith       }
22810716a85fSBarry Smith       a += m;
22820716a85fSBarry Smith     }
22830716a85fSBarry Smith   } else if (type == NORM_1) {
22840716a85fSBarry Smith     for (i=0; i<n; i++) {
22850716a85fSBarry Smith       for (j=0; j<m; j++) {
22860716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
22870716a85fSBarry Smith       }
22880716a85fSBarry Smith       a += m;
22890716a85fSBarry Smith     }
22900716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
22910716a85fSBarry Smith     for (i=0; i<n; i++) {
22920716a85fSBarry Smith       for (j=0; j<m; j++) {
22930716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
22940716a85fSBarry Smith       }
22950716a85fSBarry Smith       a += m;
22960716a85fSBarry Smith     }
2297ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
22988c778c55SBarry Smith   ierr = MatDenseRestoreArray(A,&a);CHKERRQ(ierr);
22990716a85fSBarry Smith   if (type == NORM_2) {
23008f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
23010716a85fSBarry Smith   }
23020716a85fSBarry Smith   PetscFunctionReturn(0);
23030716a85fSBarry Smith }
23040716a85fSBarry Smith 
230573a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
230673a71a0fSBarry Smith {
230773a71a0fSBarry Smith   PetscErrorCode ierr;
230873a71a0fSBarry Smith   PetscScalar    *a;
230973a71a0fSBarry Smith   PetscInt       m,n,i;
231073a71a0fSBarry Smith 
231173a71a0fSBarry Smith   PetscFunctionBegin;
231273a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
23138c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
231473a71a0fSBarry Smith   for (i=0; i<m*n; i++) {
231573a71a0fSBarry Smith     ierr = PetscRandomGetValue(rctx,a+i);CHKERRQ(ierr);
231673a71a0fSBarry Smith   }
23178c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
231873a71a0fSBarry Smith   PetscFunctionReturn(0);
231973a71a0fSBarry Smith }
232073a71a0fSBarry Smith 
23213b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
23223b49f96aSBarry Smith {
23233b49f96aSBarry Smith   PetscFunctionBegin;
23243b49f96aSBarry Smith   *missing = PETSC_FALSE;
23253b49f96aSBarry Smith   PetscFunctionReturn(0);
23263b49f96aSBarry Smith }
232773a71a0fSBarry Smith 
2328af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
232986aefd0dSHong Zhang {
233086aefd0dSHong Zhang   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
233186aefd0dSHong Zhang 
233286aefd0dSHong Zhang   PetscFunctionBegin;
233386aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
233486aefd0dSHong Zhang   *vals = a->v+col*a->lda;
233586aefd0dSHong Zhang   PetscFunctionReturn(0);
233686aefd0dSHong Zhang }
233786aefd0dSHong Zhang 
2338af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
233986aefd0dSHong Zhang {
234086aefd0dSHong Zhang   PetscFunctionBegin;
234186aefd0dSHong Zhang   *vals = 0; /* user cannot accidently use the array later */
234286aefd0dSHong Zhang   PetscFunctionReturn(0);
234386aefd0dSHong Zhang }
2344abc3b08eSStefano Zampini 
2345289bc588SBarry Smith /* -------------------------------------------------------------------*/
2346a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2347905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2348905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2349905e6a2fSBarry Smith                                         MatMult_SeqDense,
235097304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
23517c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
23527c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2353db4efbfdSBarry Smith                                         0,
2354db4efbfdSBarry Smith                                         0,
2355db4efbfdSBarry Smith                                         0,
2356db4efbfdSBarry Smith                                 /* 10*/ 0,
2357905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2358905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
235941f059aeSBarry Smith                                         MatSOR_SeqDense,
2360ec8511deSBarry Smith                                         MatTranspose_SeqDense,
236197304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2362905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2363905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2364905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2365905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2366c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2367c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2368905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2369905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2370d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2371db4efbfdSBarry Smith                                         0,
2372db4efbfdSBarry Smith                                         0,
2373db4efbfdSBarry Smith                                         0,
2374db4efbfdSBarry Smith                                         0,
23754994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2376273d9f13SBarry Smith                                         0,
2377905e6a2fSBarry Smith                                         0,
237873a71a0fSBarry Smith                                         0,
237973a71a0fSBarry Smith                                         0,
2380d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2381a5ae1ecdSBarry Smith                                         0,
2382a5ae1ecdSBarry Smith                                         0,
2383a5ae1ecdSBarry Smith                                         0,
2384a5ae1ecdSBarry Smith                                         0,
2385d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
23867dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2387a5ae1ecdSBarry Smith                                         0,
23884b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2389a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2390d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2391a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
23927d68702bSBarry Smith                                         MatShift_Basic,
2393a5ae1ecdSBarry Smith                                         0,
23943f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
239573a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2396a5ae1ecdSBarry Smith                                         0,
2397a5ae1ecdSBarry Smith                                         0,
2398a5ae1ecdSBarry Smith                                         0,
2399a5ae1ecdSBarry Smith                                         0,
2400d519adbfSMatthew Knepley                                 /* 54*/ 0,
2401a5ae1ecdSBarry Smith                                         0,
2402a5ae1ecdSBarry Smith                                         0,
2403a5ae1ecdSBarry Smith                                         0,
2404a5ae1ecdSBarry Smith                                         0,
2405d519adbfSMatthew Knepley                                 /* 59*/ 0,
2406e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2407e03a110bSBarry Smith                                         MatView_SeqDense,
2408357abbc8SBarry Smith                                         0,
240997304618SKris Buschelman                                         0,
2410d519adbfSMatthew Knepley                                 /* 64*/ 0,
241197304618SKris Buschelman                                         0,
241297304618SKris Buschelman                                         0,
241397304618SKris Buschelman                                         0,
241497304618SKris Buschelman                                         0,
2415d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
241697304618SKris Buschelman                                         0,
241797304618SKris Buschelman                                         0,
241897304618SKris Buschelman                                         0,
241997304618SKris Buschelman                                         0,
2420d519adbfSMatthew Knepley                                 /* 74*/ 0,
242197304618SKris Buschelman                                         0,
242297304618SKris Buschelman                                         0,
242397304618SKris Buschelman                                         0,
242497304618SKris Buschelman                                         0,
2425d519adbfSMatthew Knepley                                 /* 79*/ 0,
242697304618SKris Buschelman                                         0,
242797304618SKris Buschelman                                         0,
242897304618SKris Buschelman                                         0,
24295bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2430865e5f61SKris Buschelman                                         0,
24311cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2432865e5f61SKris Buschelman                                         0,
2433865e5f61SKris Buschelman                                         0,
2434865e5f61SKris Buschelman                                         0,
2435d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqDense_SeqDense,
2436a9fe9ddaSSatish Balay                                         MatMatMultSymbolic_SeqDense_SeqDense,
2437a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2438abc3b08eSStefano Zampini                                         MatPtAP_SeqDense_SeqDense,
2439abc3b08eSStefano Zampini                                         MatPtAPSymbolic_SeqDense_SeqDense,
2440abc3b08eSStefano Zampini                                 /* 94*/ MatPtAPNumeric_SeqDense_SeqDense,
244169f65d41SStefano Zampini                                         MatMatTransposeMult_SeqDense_SeqDense,
244269f65d41SStefano Zampini                                         MatMatTransposeMultSymbolic_SeqDense_SeqDense,
244369f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2444284134d9SBarry Smith                                         0,
2445d519adbfSMatthew Knepley                                 /* 99*/ 0,
2446284134d9SBarry Smith                                         0,
2447284134d9SBarry Smith                                         0,
2448ba337c44SJed Brown                                         MatConjugate_SeqDense,
2449f73d5cc4SBarry Smith                                         0,
2450ba337c44SJed Brown                                 /*104*/ 0,
2451ba337c44SJed Brown                                         MatRealPart_SeqDense,
2452ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2453985db425SBarry Smith                                         0,
2454985db425SBarry Smith                                         0,
24558208b9aeSStefano Zampini                                 /*109*/ 0,
2456985db425SBarry Smith                                         0,
24578d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2458aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
24593b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2460aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2461aabbc4fbSShri Abhyankar                                         0,
2462aabbc4fbSShri Abhyankar                                         0,
2463aabbc4fbSShri Abhyankar                                         0,
2464aabbc4fbSShri Abhyankar                                         0,
2465aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2466aabbc4fbSShri Abhyankar                                         0,
2467aabbc4fbSShri Abhyankar                                         0,
24680716a85fSBarry Smith                                         0,
24690716a85fSBarry Smith                                         0,
24700716a85fSBarry Smith                                 /*124*/ 0,
24715df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
24725df89d91SHong Zhang                                         0,
24735df89d91SHong Zhang                                         0,
24745df89d91SHong Zhang                                         0,
24755df89d91SHong Zhang                                 /*129*/ 0,
247675648e8dSHong Zhang                                         MatTransposeMatMult_SeqDense_SeqDense,
247775648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqDense_SeqDense,
247875648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
24793964eb88SJed Brown                                         0,
24803964eb88SJed Brown                                 /*134*/ 0,
24813964eb88SJed Brown                                         0,
24823964eb88SJed Brown                                         0,
24833964eb88SJed Brown                                         0,
24843964eb88SJed Brown                                         0,
24853964eb88SJed Brown                                 /*139*/ 0,
2486f9426fe0SMark Adams                                         0,
2487d528f656SJakub Kruzik                                         0,
2488d528f656SJakub Kruzik                                         0,
2489d528f656SJakub Kruzik                                         0,
2490d528f656SJakub Kruzik                                 /*144*/ MatCreateMPIMatConcatenateSeqMat_SeqDense
2491985db425SBarry Smith };
249290ace30eSBarry Smith 
24934b828684SBarry Smith /*@C
2494fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2495d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2496d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2497289bc588SBarry Smith 
2498db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2499db81eaa0SLois Curfman McInnes 
250020563c6bSBarry Smith    Input Parameters:
2501db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
25020c775827SLois Curfman McInnes .  m - number of rows
250318f449edSLois Curfman McInnes .  n - number of columns
25040298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2505dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
250620563c6bSBarry Smith 
250720563c6bSBarry Smith    Output Parameter:
250844cd7ae7SLois Curfman McInnes .  A - the matrix
250920563c6bSBarry Smith 
2510b259b22eSLois Curfman McInnes    Notes:
251118f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
251218f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
25130298fd71SBarry Smith    set data=NULL.
251418f449edSLois Curfman McInnes 
2515027ccd11SLois Curfman McInnes    Level: intermediate
2516027ccd11SLois Curfman McInnes 
2517dbd7a890SLois Curfman McInnes .keywords: dense, matrix, LAPACK, BLAS
2518d65003e9SLois Curfman McInnes 
251969b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
252020563c6bSBarry Smith @*/
25217087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2522289bc588SBarry Smith {
2523dfbe8321SBarry Smith   PetscErrorCode ierr;
25243b2fbd54SBarry Smith 
25253a40ed3dSBarry Smith   PetscFunctionBegin;
2526f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2527f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2528273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2529273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2530273d9f13SBarry Smith   PetscFunctionReturn(0);
2531273d9f13SBarry Smith }
2532273d9f13SBarry Smith 
2533273d9f13SBarry Smith /*@C
2534273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2535273d9f13SBarry Smith 
2536273d9f13SBarry Smith    Collective on MPI_Comm
2537273d9f13SBarry Smith 
2538273d9f13SBarry Smith    Input Parameters:
25391c4f3114SJed Brown +  B - the matrix
25400298fd71SBarry Smith -  data - the array (or NULL)
2541273d9f13SBarry Smith 
2542273d9f13SBarry Smith    Notes:
2543273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2544273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2545284134d9SBarry Smith    need not call this routine.
2546273d9f13SBarry Smith 
2547273d9f13SBarry Smith    Level: intermediate
2548273d9f13SBarry Smith 
2549273d9f13SBarry Smith .keywords: dense, matrix, LAPACK, BLAS
2550273d9f13SBarry Smith 
255169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA()
2552867c911aSBarry Smith 
2553273d9f13SBarry Smith @*/
25547087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2555273d9f13SBarry Smith {
25564ac538c5SBarry Smith   PetscErrorCode ierr;
2557a23d5eceSKris Buschelman 
2558a23d5eceSKris Buschelman   PetscFunctionBegin;
25594ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2560a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2561a23d5eceSKris Buschelman }
2562a23d5eceSKris Buschelman 
25637087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2564a23d5eceSKris Buschelman {
2565273d9f13SBarry Smith   Mat_SeqDense   *b;
2566dfbe8321SBarry Smith   PetscErrorCode ierr;
2567273d9f13SBarry Smith 
2568273d9f13SBarry Smith   PetscFunctionBegin;
2569273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2570a868139aSShri Abhyankar 
257134ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
257234ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
257334ef9618SShri Abhyankar 
2574273d9f13SBarry Smith   b       = (Mat_SeqDense*)B->data;
257586d161a7SShri Abhyankar   b->Mmax = B->rmap->n;
257686d161a7SShri Abhyankar   b->Nmax = B->cmap->n;
257786d161a7SShri Abhyankar   if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n;
257886d161a7SShri Abhyankar 
2579220afb94SBarry Smith   ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr);
25809e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
25819e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2582e92229d0SSatish Balay     ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr);
25833bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
25842205254eSKarl Rupp 
25859e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2586273d9f13SBarry Smith   } else { /* user-allocated storage */
25879e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2588273d9f13SBarry Smith     b->v          = data;
2589273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2590273d9f13SBarry Smith   }
25910450473dSBarry Smith   B->assembled = PETSC_TRUE;
2592273d9f13SBarry Smith   PetscFunctionReturn(0);
2593273d9f13SBarry Smith }
2594273d9f13SBarry Smith 
259565b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2596cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
25978baccfbdSHong Zhang {
2598d77f618aSHong Zhang   Mat            mat_elemental;
2599d77f618aSHong Zhang   PetscErrorCode ierr;
2600d77f618aSHong Zhang   PetscScalar    *array,*v_colwise;
2601d77f618aSHong Zhang   PetscInt       M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2602d77f618aSHong Zhang 
26038baccfbdSHong Zhang   PetscFunctionBegin;
2604d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
2605d77f618aSHong Zhang   ierr = MatDenseGetArray(A,&array);CHKERRQ(ierr);
2606d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2607d77f618aSHong Zhang   k = 0;
2608d77f618aSHong Zhang   for (j=0; j<N; j++) {
2609d77f618aSHong Zhang     cols[j] = j;
2610d77f618aSHong Zhang     for (i=0; i<M; i++) {
2611d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2612d77f618aSHong Zhang     }
2613d77f618aSHong Zhang   }
2614d77f618aSHong Zhang   for (i=0; i<M; i++) {
2615d77f618aSHong Zhang     rows[i] = i;
2616d77f618aSHong Zhang   }
2617d77f618aSHong Zhang   ierr = MatDenseRestoreArray(A,&array);CHKERRQ(ierr);
2618d77f618aSHong Zhang 
2619d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2620d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2621d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2622d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2623d77f618aSHong Zhang 
2624d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2625d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2626d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2627d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2628d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2629d77f618aSHong Zhang 
2630511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
263128be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2632d77f618aSHong Zhang   } else {
2633d77f618aSHong Zhang     *newmat = mat_elemental;
2634d77f618aSHong Zhang   }
26358baccfbdSHong Zhang   PetscFunctionReturn(0);
26368baccfbdSHong Zhang }
263765b80a83SHong Zhang #endif
26388baccfbdSHong Zhang 
26391b807ce4Svictorle /*@C
26401b807ce4Svictorle   MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array
26411b807ce4Svictorle 
26421b807ce4Svictorle   Input parameter:
26431b807ce4Svictorle + A - the matrix
26441b807ce4Svictorle - lda - the leading dimension
26451b807ce4Svictorle 
26461b807ce4Svictorle   Notes:
2647867c911aSBarry Smith   This routine is to be used in conjunction with MatSeqDenseSetPreallocation();
26481b807ce4Svictorle   it asserts that the preallocation has a leading dimension (the LDA parameter
26491b807ce4Svictorle   of Blas and Lapack fame) larger than M, the first dimension of the matrix.
26501b807ce4Svictorle 
26511b807ce4Svictorle   Level: intermediate
26521b807ce4Svictorle 
26531b807ce4Svictorle .keywords: dense, matrix, LAPACK, BLAS
26541b807ce4Svictorle 
2655284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize()
2656867c911aSBarry Smith 
26571b807ce4Svictorle @*/
26587087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetLDA(Mat B,PetscInt lda)
26591b807ce4Svictorle {
26601b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
266121a2c019SBarry Smith 
26621b807ce4Svictorle   PetscFunctionBegin;
2663e32f2f54SBarry 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);
26641b807ce4Svictorle   b->lda       = lda;
266521a2c019SBarry Smith   b->changelda = PETSC_FALSE;
266621a2c019SBarry Smith   b->Mmax      = PetscMax(b->Mmax,lda);
26671b807ce4Svictorle   PetscFunctionReturn(0);
26681b807ce4Svictorle }
26691b807ce4Svictorle 
2670d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
2671d528f656SJakub Kruzik {
2672d528f656SJakub Kruzik   PetscErrorCode ierr;
2673d528f656SJakub Kruzik   PetscMPIInt    size;
2674d528f656SJakub Kruzik 
2675d528f656SJakub Kruzik   PetscFunctionBegin;
2676d528f656SJakub Kruzik   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2677d528f656SJakub Kruzik   if (size == 1) {
2678d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
2679d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
2680d528f656SJakub Kruzik     } else {
2681d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2682d528f656SJakub Kruzik     }
2683d528f656SJakub Kruzik   } else {
2684d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
2685d528f656SJakub Kruzik   }
2686d528f656SJakub Kruzik   PetscFunctionReturn(0);
2687d528f656SJakub Kruzik }
2688d528f656SJakub Kruzik 
26890bad9183SKris Buschelman /*MC
2690fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
26910bad9183SKris Buschelman 
26920bad9183SKris Buschelman    Options Database Keys:
26930bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
26940bad9183SKris Buschelman 
26950bad9183SKris Buschelman   Level: beginner
26960bad9183SKris Buschelman 
269789665df3SBarry Smith .seealso: MatCreateSeqDense()
269889665df3SBarry Smith 
26990bad9183SKris Buschelman M*/
27000bad9183SKris Buschelman 
27018cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqDense(Mat B)
2702273d9f13SBarry Smith {
2703273d9f13SBarry Smith   Mat_SeqDense   *b;
2704dfbe8321SBarry Smith   PetscErrorCode ierr;
27057c334f02SBarry Smith   PetscMPIInt    size;
2706273d9f13SBarry Smith 
2707273d9f13SBarry Smith   PetscFunctionBegin;
2708ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
2709e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
271055659b69SBarry Smith 
2711b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
2712549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
271344cd7ae7SLois Curfman McInnes   B->data = (void*)b;
271418f449edSLois Curfman McInnes 
2715273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
27164e220ebcSLois Curfman McInnes 
2717bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
27188572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2719d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
2720d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
27218572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2722715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2723bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
27248baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
27258baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
27268baccfbdSHong Zhang #endif
2727bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
2728bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaij_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2729bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2730bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2731abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaij_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
27324099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijperm_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
27334099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijperm_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
27344099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijperm_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
27354099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijperm_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
2736e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijsell_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2737e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijsell_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2738e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijsell_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2739e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijsell_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
274096e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijmkl_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
274196e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijmkl_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
274296e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijmkl_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
274396e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijmkl_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
274496e6d5c4SRichard Tran Mills 
27453bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaij_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
27463bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
27473bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
27484099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijperm_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
27494099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
27504099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2751e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijsell_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2752e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2753e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
275496e6d5c4SRichard Tran Mills 
275596e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijmkl_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
275696e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
275796e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2758af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
2759af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
276017667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
27613a40ed3dSBarry Smith   PetscFunctionReturn(0);
2762289bc588SBarry Smith }
276386aefd0dSHong Zhang 
276486aefd0dSHong Zhang /*@C
2765af53bab2SHong 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.
276686aefd0dSHong Zhang 
276786aefd0dSHong Zhang    Not Collective
276886aefd0dSHong Zhang 
276986aefd0dSHong Zhang    Input Parameter:
277086aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
277186aefd0dSHong Zhang -  col - column index
277286aefd0dSHong Zhang 
277386aefd0dSHong Zhang    Output Parameter:
277486aefd0dSHong Zhang .  vals - pointer to the data
277586aefd0dSHong Zhang 
277686aefd0dSHong Zhang    Level: intermediate
277786aefd0dSHong Zhang 
277886aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
277986aefd0dSHong Zhang @*/
278086aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
278186aefd0dSHong Zhang {
278286aefd0dSHong Zhang   PetscErrorCode ierr;
278386aefd0dSHong Zhang 
278486aefd0dSHong Zhang   PetscFunctionBegin;
278586aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
278686aefd0dSHong Zhang   PetscFunctionReturn(0);
278786aefd0dSHong Zhang }
278886aefd0dSHong Zhang 
278986aefd0dSHong Zhang /*@C
279086aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
279186aefd0dSHong Zhang 
279286aefd0dSHong Zhang    Not Collective
279386aefd0dSHong Zhang 
279486aefd0dSHong Zhang    Input Parameter:
279586aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
279686aefd0dSHong Zhang 
279786aefd0dSHong Zhang    Output Parameter:
279886aefd0dSHong Zhang .  vals - pointer to the data
279986aefd0dSHong Zhang 
280086aefd0dSHong Zhang    Level: intermediate
280186aefd0dSHong Zhang 
280286aefd0dSHong Zhang .seealso: MatDenseGetColumn()
280386aefd0dSHong Zhang @*/
280486aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
280586aefd0dSHong Zhang {
280686aefd0dSHong Zhang   PetscErrorCode ierr;
280786aefd0dSHong Zhang 
280886aefd0dSHong Zhang   PetscFunctionBegin;
280986aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
281086aefd0dSHong Zhang   PetscFunctionReturn(0);
281186aefd0dSHong Zhang }
2812