xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 49a6ff4bde1c92b5077fb1a754cc0af9d6e18201)
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) {
1166c4d906cSStefano Zampini     Vec xt;
1176c4d906cSStefano Zampini 
1186c4d906cSStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1196c4d906cSStefano Zampini     ierr = VecDuplicate(x,&xt);CHKERRQ(ierr);
1206c4d906cSStefano Zampini     ierr = VecCopy(x,xt);CHKERRQ(ierr);
1216c4d906cSStefano Zampini     ierr = VecScale(xt,-1.0);CHKERRQ(ierr);
1226c4d906cSStefano Zampini     ierr = MatMultAdd(A,xt,b,b);CHKERRQ(ierr);
1236c4d906cSStefano Zampini     ierr = VecDestroy(&xt);CHKERRQ(ierr);
1243f49a652SStefano Zampini     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1253f49a652SStefano Zampini     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
1263f49a652SStefano Zampini     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
1273f49a652SStefano Zampini     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1283f49a652SStefano Zampini     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
1293f49a652SStefano Zampini   }
1303f49a652SStefano Zampini 
1313f49a652SStefano Zampini   for (i=0; i<N; i++) {
1323f49a652SStefano Zampini     slot = l->v + rows[i]*m;
1333f49a652SStefano Zampini     ierr = PetscMemzero(slot,r*sizeof(PetscScalar));CHKERRQ(ierr);
1343f49a652SStefano Zampini   }
1353f49a652SStefano Zampini   for (i=0; i<N; i++) {
1363f49a652SStefano Zampini     slot = l->v + rows[i];
1373f49a652SStefano Zampini     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
1383f49a652SStefano Zampini   }
1393f49a652SStefano Zampini   if (diag != 0.0) {
1403f49a652SStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1413f49a652SStefano Zampini     for (i=0; i<N; i++) {
1423f49a652SStefano Zampini       slot  = l->v + (m+1)*rows[i];
1433f49a652SStefano Zampini       *slot = diag;
1443f49a652SStefano Zampini     }
1453f49a652SStefano Zampini   }
1463f49a652SStefano Zampini   PetscFunctionReturn(0);
1473f49a652SStefano Zampini }
1483f49a652SStefano Zampini 
149abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C)
150abc3b08eSStefano Zampini {
151abc3b08eSStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)(C->data);
152abc3b08eSStefano Zampini   PetscErrorCode ierr;
153abc3b08eSStefano Zampini 
154abc3b08eSStefano Zampini   PetscFunctionBegin;
155abc3b08eSStefano Zampini   ierr = MatMatMultNumeric_SeqDense_SeqDense(A,P,c->ptapwork);CHKERRQ(ierr);
156abc3b08eSStefano Zampini   ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(P,c->ptapwork,C);CHKERRQ(ierr);
157abc3b08eSStefano Zampini   PetscFunctionReturn(0);
158abc3b08eSStefano Zampini }
159abc3b08eSStefano Zampini 
160abc3b08eSStefano Zampini PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat *C)
161abc3b08eSStefano Zampini {
162abc3b08eSStefano Zampini   Mat_SeqDense   *c;
163abc3b08eSStefano Zampini   PetscErrorCode ierr;
164abc3b08eSStefano Zampini 
165abc3b08eSStefano Zampini   PetscFunctionBegin;
166abc3b08eSStefano Zampini   ierr = MatCreateSeqDense(PetscObjectComm((PetscObject)A),P->cmap->N,P->cmap->N,NULL,C);CHKERRQ(ierr);
167abc3b08eSStefano Zampini   c = (Mat_SeqDense*)((*C)->data);
168abc3b08eSStefano Zampini   ierr = MatCreateSeqDense(PetscObjectComm((PetscObject)A),A->rmap->N,P->cmap->N,NULL,&c->ptapwork);CHKERRQ(ierr);
169abc3b08eSStefano Zampini   PetscFunctionReturn(0);
170abc3b08eSStefano Zampini }
171abc3b08eSStefano Zampini 
172150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatPtAP_SeqDense_SeqDense(Mat A,Mat P,MatReuse reuse,PetscReal fill,Mat *C)
173abc3b08eSStefano Zampini {
174abc3b08eSStefano Zampini   PetscErrorCode ierr;
175abc3b08eSStefano Zampini 
176abc3b08eSStefano Zampini   PetscFunctionBegin;
177abc3b08eSStefano Zampini   if (reuse == MAT_INITIAL_MATRIX) {
178abc3b08eSStefano Zampini     ierr = MatPtAPSymbolic_SeqDense_SeqDense(A,P,fill,C);CHKERRQ(ierr);
179abc3b08eSStefano Zampini   }
180abc3b08eSStefano Zampini   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
181abc3b08eSStefano Zampini   ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
182abc3b08eSStefano Zampini   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
183abc3b08eSStefano Zampini   PetscFunctionReturn(0);
184abc3b08eSStefano Zampini }
185abc3b08eSStefano Zampini 
186cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
187b49cda9fSStefano Zampini {
188a13144ffSStefano Zampini   Mat            B = NULL;
189b49cda9fSStefano Zampini   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
190b49cda9fSStefano Zampini   Mat_SeqDense   *b;
191b49cda9fSStefano Zampini   PetscErrorCode ierr;
192b49cda9fSStefano Zampini   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i;
193b49cda9fSStefano Zampini   MatScalar      *av=a->a;
194a13144ffSStefano Zampini   PetscBool      isseqdense;
195b49cda9fSStefano Zampini 
196b49cda9fSStefano Zampini   PetscFunctionBegin;
197a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
198a13144ffSStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense);CHKERRQ(ierr);
199a13144ffSStefano Zampini     if (!isseqdense) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type);
200a13144ffSStefano Zampini   }
201a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
202b49cda9fSStefano Zampini     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
203b49cda9fSStefano Zampini     ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
204b49cda9fSStefano Zampini     ierr = MatSetType(B,MATSEQDENSE);CHKERRQ(ierr);
205b49cda9fSStefano Zampini     ierr = MatSeqDenseSetPreallocation(B,NULL);CHKERRQ(ierr);
206b49cda9fSStefano Zampini     b    = (Mat_SeqDense*)(B->data);
207a13144ffSStefano Zampini   } else {
208a13144ffSStefano Zampini     b    = (Mat_SeqDense*)((*newmat)->data);
209a13144ffSStefano Zampini     ierr = PetscMemzero(b->v,m*n*sizeof(PetscScalar));CHKERRQ(ierr);
210a13144ffSStefano Zampini   }
211b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
212b49cda9fSStefano Zampini     PetscInt j;
213b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
214b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
215b49cda9fSStefano Zampini       aj++;
216b49cda9fSStefano Zampini       av++;
217b49cda9fSStefano Zampini     }
218b49cda9fSStefano Zampini     ai++;
219b49cda9fSStefano Zampini   }
220b49cda9fSStefano Zampini 
221511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
222a13144ffSStefano Zampini     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
223a13144ffSStefano Zampini     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22428be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
225b49cda9fSStefano Zampini   } else {
226a13144ffSStefano Zampini     if (B) *newmat = B;
227a13144ffSStefano Zampini     ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
228a13144ffSStefano Zampini     ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
229b49cda9fSStefano Zampini   }
230b49cda9fSStefano Zampini   PetscFunctionReturn(0);
231b49cda9fSStefano Zampini }
232b49cda9fSStefano Zampini 
233cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
2346a63e612SBarry Smith {
2356a63e612SBarry Smith   Mat            B;
2366a63e612SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2376a63e612SBarry Smith   PetscErrorCode ierr;
2389399e1b8SMatthew G. Knepley   PetscInt       i, j;
2399399e1b8SMatthew G. Knepley   PetscInt       *rows, *nnz;
2409399e1b8SMatthew G. Knepley   MatScalar      *aa = a->v, *vals;
2416a63e612SBarry Smith 
2426a63e612SBarry Smith   PetscFunctionBegin;
243ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
2446a63e612SBarry Smith   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
2456a63e612SBarry Smith   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
2469399e1b8SMatthew G. Knepley   ierr = PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals);CHKERRQ(ierr);
2479399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2489399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) ++nnz[i];
2496a63e612SBarry Smith     aa += a->lda;
2506a63e612SBarry Smith   }
2519399e1b8SMatthew G. Knepley   ierr = MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz);CHKERRQ(ierr);
2529399e1b8SMatthew G. Knepley   aa = a->v;
2539399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2549399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2559399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) {rows[numRows] = i; vals[numRows++] = aa[i];}
2569399e1b8SMatthew G. Knepley     ierr = MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr);
2579399e1b8SMatthew G. Knepley     aa  += a->lda;
2589399e1b8SMatthew G. Knepley   }
2599399e1b8SMatthew G. Knepley   ierr = PetscFree3(rows,nnz,vals);CHKERRQ(ierr);
2606a63e612SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2616a63e612SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2626a63e612SBarry Smith 
263511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
26428be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
2656a63e612SBarry Smith   } else {
2666a63e612SBarry Smith     *newmat = B;
2676a63e612SBarry Smith   }
2686a63e612SBarry Smith   PetscFunctionReturn(0);
2696a63e612SBarry Smith }
2706a63e612SBarry Smith 
271e0877f53SBarry Smith static PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
2721987afe7SBarry Smith {
2731987afe7SBarry Smith   Mat_SeqDense   *x     = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
274f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
27513f74950SBarry Smith   PetscInt       j;
2760805154bSBarry Smith   PetscBLASInt   N,m,ldax,lday,one = 1;
277efee365bSSatish Balay   PetscErrorCode ierr;
2783a40ed3dSBarry Smith 
2793a40ed3dSBarry Smith   PetscFunctionBegin;
280c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n*X->cmap->n,&N);CHKERRQ(ierr);
281c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n,&m);CHKERRQ(ierr);
282c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->lda,&ldax);CHKERRQ(ierr);
283c5df96a5SBarry Smith   ierr = PetscBLASIntCast(y->lda,&lday);CHKERRQ(ierr);
284a5ce6ee0Svictorle   if (ldax>m || lday>m) {
285d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
2868b83055fSJed Brown       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&oalpha,x->v+j*ldax,&one,y->v+j*lday,&one));
287a5ce6ee0Svictorle     }
288a5ce6ee0Svictorle   } else {
2898b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&oalpha,x->v,&one,y->v,&one));
290a5ce6ee0Svictorle   }
291a3fa217bSJose E. Roman   ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr);
2920450473dSBarry Smith   ierr = PetscLogFlops(PetscMax(2*N-1,0));CHKERRQ(ierr);
2933a40ed3dSBarry Smith   PetscFunctionReturn(0);
2941987afe7SBarry Smith }
2951987afe7SBarry Smith 
296e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
297289bc588SBarry Smith {
298d0f46423SBarry Smith   PetscInt N = A->rmap->n*A->cmap->n;
2993a40ed3dSBarry Smith 
3003a40ed3dSBarry Smith   PetscFunctionBegin;
3014e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
3024e220ebcSLois Curfman McInnes   info->nz_allocated      = (double)N;
3036de62eeeSBarry Smith   info->nz_used           = (double)N;
3046de62eeeSBarry Smith   info->nz_unneeded       = (double)0;
3054e220ebcSLois Curfman McInnes   info->assemblies        = (double)A->num_ass;
3064e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3077adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3084e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3094e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3104e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3113a40ed3dSBarry Smith   PetscFunctionReturn(0);
312289bc588SBarry Smith }
313289bc588SBarry Smith 
314e0877f53SBarry Smith static PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
31580cd9d93SLois Curfman McInnes {
316273d9f13SBarry Smith   Mat_SeqDense   *a     = (Mat_SeqDense*)A->data;
317f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
318efee365bSSatish Balay   PetscErrorCode ierr;
319c5df96a5SBarry Smith   PetscBLASInt   one = 1,j,nz,lda;
32080cd9d93SLois Curfman McInnes 
3213a40ed3dSBarry Smith   PetscFunctionBegin;
322c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->lda,&lda);CHKERRQ(ierr);
323d0f46423SBarry Smith   if (lda>A->rmap->n) {
324c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n,&nz);CHKERRQ(ierr);
325d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
3268b83055fSJed Brown       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&oalpha,a->v+j*lda,&one));
327a5ce6ee0Svictorle     }
328a5ce6ee0Svictorle   } else {
329c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz);CHKERRQ(ierr);
3308b83055fSJed Brown     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&oalpha,a->v,&one));
331a5ce6ee0Svictorle   }
332efee365bSSatish Balay   ierr = PetscLogFlops(nz);CHKERRQ(ierr);
3333a40ed3dSBarry Smith   PetscFunctionReturn(0);
33480cd9d93SLois Curfman McInnes }
33580cd9d93SLois Curfman McInnes 
336e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3371cbb95d3SBarry Smith {
3381cbb95d3SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
339d0f46423SBarry Smith   PetscInt     i,j,m = A->rmap->n,N;
3401cbb95d3SBarry Smith   PetscScalar  *v = a->v;
3411cbb95d3SBarry Smith 
3421cbb95d3SBarry Smith   PetscFunctionBegin;
3431cbb95d3SBarry Smith   *fl = PETSC_FALSE;
344d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3451cbb95d3SBarry Smith   N = a->lda;
3461cbb95d3SBarry Smith 
3471cbb95d3SBarry Smith   for (i=0; i<m; i++) {
3481cbb95d3SBarry Smith     for (j=i+1; j<m; j++) {
3491cbb95d3SBarry Smith       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) PetscFunctionReturn(0);
3501cbb95d3SBarry Smith     }
3511cbb95d3SBarry Smith   }
3521cbb95d3SBarry Smith   *fl = PETSC_TRUE;
3531cbb95d3SBarry Smith   PetscFunctionReturn(0);
3541cbb95d3SBarry Smith }
3551cbb95d3SBarry Smith 
356e0877f53SBarry Smith static PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
357b24902e0SBarry Smith {
358b24902e0SBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data,*l;
359b24902e0SBarry Smith   PetscErrorCode ierr;
360b24902e0SBarry Smith   PetscInt       lda = (PetscInt)mat->lda,j,m;
361b24902e0SBarry Smith 
362b24902e0SBarry Smith   PetscFunctionBegin;
363aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr);
364aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr);
3650298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr);
366b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
367b24902e0SBarry Smith     l = (Mat_SeqDense*)newi->data;
368d0f46423SBarry Smith     if (lda>A->rmap->n) {
369d0f46423SBarry Smith       m = A->rmap->n;
370d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
371b24902e0SBarry Smith         ierr = PetscMemcpy(l->v+j*m,mat->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr);
372b24902e0SBarry Smith       }
373b24902e0SBarry Smith     } else {
374d0f46423SBarry Smith       ierr = PetscMemcpy(l->v,mat->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
375b24902e0SBarry Smith     }
376b24902e0SBarry Smith   }
377b24902e0SBarry Smith   newi->assembled = PETSC_TRUE;
378b24902e0SBarry Smith   PetscFunctionReturn(0);
379b24902e0SBarry Smith }
380b24902e0SBarry Smith 
381e0877f53SBarry Smith static PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
38202cad45dSBarry Smith {
3836849ba73SBarry Smith   PetscErrorCode ierr;
38402cad45dSBarry Smith 
3853a40ed3dSBarry Smith   PetscFunctionBegin;
386ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr);
387d0f46423SBarry Smith   ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
3885c9eb25fSBarry Smith   ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
389719d5645SBarry Smith   ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr);
390b24902e0SBarry Smith   PetscFunctionReturn(0);
391b24902e0SBarry Smith }
392b24902e0SBarry Smith 
3936ee01492SSatish Balay 
394e0877f53SBarry Smith static PetscErrorCode MatLUFactor_SeqDense(Mat,IS,IS,const MatFactorInfo*);
395719d5645SBarry Smith 
396e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
397289bc588SBarry Smith {
3984482741eSBarry Smith   MatFactorInfo  info;
399a093e273SMatthew Knepley   PetscErrorCode ierr;
4003a40ed3dSBarry Smith 
4013a40ed3dSBarry Smith   PetscFunctionBegin;
402c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
403719d5645SBarry Smith   ierr = MatLUFactor_SeqDense(fact,0,0,&info);CHKERRQ(ierr);
4043a40ed3dSBarry Smith   PetscFunctionReturn(0);
405289bc588SBarry Smith }
4066ee01492SSatish Balay 
407e0877f53SBarry Smith static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy)
408289bc588SBarry Smith {
409c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
4106849ba73SBarry Smith   PetscErrorCode    ierr;
411f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
412f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
413c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
41467e560aaSBarry Smith 
4153a40ed3dSBarry Smith   PetscFunctionBegin;
416c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
417f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4181ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
419d0f46423SBarry Smith   ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
420d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_LU) {
421ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
422e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
423ae7cfcebSSatish Balay #else
42400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4258b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
42600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
427e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
428ae7cfcebSSatish Balay #endif
429d5f3da31SBarry Smith   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
430ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
431e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
432ae7cfcebSSatish Balay #else
433a49dc2a2SStefano Zampini     if (A->spd) {
43400121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4358b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
43600121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
437e32f2f54SBarry Smith       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
438a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
439a49dc2a2SStefano Zampini     } else if (A->hermitian) {
44000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
441a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
44200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
443a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
444a49dc2a2SStefano Zampini #endif
445a49dc2a2SStefano Zampini     } else { /* symmetric case */
44600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
447a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
44800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
449a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
450a49dc2a2SStefano Zampini     }
451ae7cfcebSSatish Balay #endif
4522205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
453f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4541ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
455dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
4563a40ed3dSBarry Smith   PetscFunctionReturn(0);
457289bc588SBarry Smith }
4586ee01492SSatish Balay 
459e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X)
46085e2c93fSHong Zhang {
46185e2c93fSHong Zhang   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
46285e2c93fSHong Zhang   PetscErrorCode ierr;
46385e2c93fSHong Zhang   PetscScalar    *b,*x;
464efb80c78SLisandro Dalcin   PetscInt       n;
465783b601eSJed Brown   PetscBLASInt   nrhs,info,m;
466bda8bf91SBarry Smith   PetscBool      flg;
46785e2c93fSHong Zhang 
46885e2c93fSHong Zhang   PetscFunctionBegin;
469c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
4700298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
471ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
4720298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
473ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
474bda8bf91SBarry Smith 
4750298fd71SBarry Smith   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
476c5df96a5SBarry Smith   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
4778c778c55SBarry Smith   ierr = MatDenseGetArray(B,&b);CHKERRQ(ierr);
4788c778c55SBarry Smith   ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr);
47985e2c93fSHong Zhang 
480f272c775SHong Zhang   ierr = PetscMemcpy(x,b,m*nrhs*sizeof(PetscScalar));CHKERRQ(ierr);
48185e2c93fSHong Zhang 
48285e2c93fSHong Zhang   if (A->factortype == MAT_FACTOR_LU) {
48385e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_GETRS)
48485e2c93fSHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
48585e2c93fSHong Zhang #else
48600121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4878b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
48800121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
48985e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
49085e2c93fSHong Zhang #endif
49185e2c93fSHong Zhang   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
49285e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_POTRS)
49385e2c93fSHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
49485e2c93fSHong Zhang #else
495a49dc2a2SStefano Zampini     if (A->spd) {
49600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4978b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
49800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
49985e2c93fSHong Zhang       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
500a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
501a49dc2a2SStefano Zampini     } else if (A->hermitian) {
50200121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
503a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
50400121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
505a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
506a49dc2a2SStefano Zampini #endif
507a49dc2a2SStefano Zampini     } else { /* symmetric case */
50800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
509a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
51000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
511a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
512a49dc2a2SStefano Zampini     }
51385e2c93fSHong Zhang #endif
5142205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
51585e2c93fSHong Zhang 
5168c778c55SBarry Smith   ierr = MatDenseRestoreArray(B,&b);CHKERRQ(ierr);
5178c778c55SBarry Smith   ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr);
51885e2c93fSHong Zhang   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
51985e2c93fSHong Zhang   PetscFunctionReturn(0);
52085e2c93fSHong Zhang }
52185e2c93fSHong Zhang 
52200121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
52300121966SStefano Zampini 
524e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
525da3a660dSBarry Smith {
526c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
527dfbe8321SBarry Smith   PetscErrorCode    ierr;
528f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
529f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
530c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
53167e560aaSBarry Smith 
5323a40ed3dSBarry Smith   PetscFunctionBegin;
533c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
534f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5351ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
536d0f46423SBarry Smith   ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
5378208b9aeSStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
538ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
539e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
540ae7cfcebSSatish Balay #else
54100121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5428b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
54300121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
544e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve");
545ae7cfcebSSatish Balay #endif
5468208b9aeSStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
547ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
548e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
549ae7cfcebSSatish Balay #else
550a49dc2a2SStefano Zampini     if (A->spd) {
55100121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
55200121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
55300121966SStefano Zampini #endif
55400121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5558b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
55600121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
55700121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
55800121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
55900121966SStefano Zampini #endif
560a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
561a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
562a49dc2a2SStefano Zampini     } else if (A->hermitian) {
56300121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
56400121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
56500121966SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
56600121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
56700121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
568ae7cfcebSSatish Balay #endif
569a49dc2a2SStefano Zampini     } else { /* symmetric case */
57000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
571a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
57200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
573a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
574da3a660dSBarry Smith     }
575a49dc2a2SStefano Zampini #endif
576a49dc2a2SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
577f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5781ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
579dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
5803a40ed3dSBarry Smith   PetscFunctionReturn(0);
581da3a660dSBarry Smith }
5826ee01492SSatish Balay 
583e0877f53SBarry Smith static PetscErrorCode MatSolveAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
584da3a660dSBarry Smith {
585dfbe8321SBarry Smith   PetscErrorCode    ierr;
586f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
587f1ceaac6SMatthew G. Knepley   PetscScalar       *y,sone = 1.0;
588da3a660dSBarry Smith   Vec               tmp = 0;
58967e560aaSBarry Smith 
5903a40ed3dSBarry Smith   PetscFunctionBegin;
591f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5921ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
593d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
594da3a660dSBarry Smith   if (yy == zz) {
59578b31e54SBarry Smith     ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr);
5963bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)tmp);CHKERRQ(ierr);
59778b31e54SBarry Smith     ierr = VecCopy(yy,tmp);CHKERRQ(ierr);
598da3a660dSBarry Smith   }
5998208b9aeSStefano Zampini   ierr = MatSolve_SeqDense(A,xx,yy);CHKERRQ(ierr);
6006bf464f9SBarry Smith   if (tmp) {
6016bf464f9SBarry Smith     ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr);
6026bf464f9SBarry Smith     ierr = VecDestroy(&tmp);CHKERRQ(ierr);
6036bf464f9SBarry Smith   } else {
6046bf464f9SBarry Smith     ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr);
6056bf464f9SBarry Smith   }
606f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
6071ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
6088208b9aeSStefano Zampini   ierr = PetscLogFlops(A->cmap->n);CHKERRQ(ierr);
6093a40ed3dSBarry Smith   PetscFunctionReturn(0);
610da3a660dSBarry Smith }
61167e560aaSBarry Smith 
612e0877f53SBarry Smith static PetscErrorCode MatSolveTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
613da3a660dSBarry Smith {
6146849ba73SBarry Smith   PetscErrorCode    ierr;
615f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
616f1ceaac6SMatthew G. Knepley   PetscScalar       *y,sone = 1.0;
61789ae1891SBarry Smith   Vec               tmp = NULL;
61867e560aaSBarry Smith 
6193a40ed3dSBarry Smith   PetscFunctionBegin;
620d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
621f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
6221ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
623da3a660dSBarry Smith   if (yy == zz) {
62478b31e54SBarry Smith     ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr);
6253bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)tmp);CHKERRQ(ierr);
62678b31e54SBarry Smith     ierr = VecCopy(yy,tmp);CHKERRQ(ierr);
627da3a660dSBarry Smith   }
6288208b9aeSStefano Zampini   ierr = MatSolveTranspose_SeqDense(A,xx,yy);CHKERRQ(ierr);
62990f02eecSBarry Smith   if (tmp) {
6302dcb1b2aSMatthew Knepley     ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr);
6316bf464f9SBarry Smith     ierr = VecDestroy(&tmp);CHKERRQ(ierr);
6323a40ed3dSBarry Smith   } else {
6332dcb1b2aSMatthew Knepley     ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr);
63490f02eecSBarry Smith   }
635f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
6361ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
6378208b9aeSStefano Zampini   ierr = PetscLogFlops(A->cmap->n);CHKERRQ(ierr);
6383a40ed3dSBarry Smith   PetscFunctionReturn(0);
639da3a660dSBarry Smith }
640db4efbfdSBarry Smith 
641db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
642db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
643db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
644e0877f53SBarry Smith static PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
645db4efbfdSBarry Smith {
646db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_GETRF)
647db4efbfdSBarry Smith   PetscFunctionBegin;
648e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRF - Lapack routine is unavailable.");
649db4efbfdSBarry Smith #else
650db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
651db4efbfdSBarry Smith   PetscErrorCode ierr;
652db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
653db4efbfdSBarry Smith 
654db4efbfdSBarry Smith   PetscFunctionBegin;
655c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
656c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
657db4efbfdSBarry Smith   if (!mat->pivots) {
6588208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
6593bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
660db4efbfdSBarry Smith   }
661db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
6628e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6638b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
6648e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
6658e57ea43SSatish Balay 
666e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
667e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
6688208b9aeSStefano Zampini 
669db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6708208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
671db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
672db4efbfdSBarry Smith   A->ops->solveadd          = MatSolveAdd_SeqDense;
673db4efbfdSBarry Smith   A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
674d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
675db4efbfdSBarry Smith 
676f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
677f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
678f6224b95SHong Zhang 
679dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
680db4efbfdSBarry Smith #endif
681db4efbfdSBarry Smith   PetscFunctionReturn(0);
682db4efbfdSBarry Smith }
683db4efbfdSBarry Smith 
684a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
685e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
686db4efbfdSBarry Smith {
687db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_POTRF)
688db4efbfdSBarry Smith   PetscFunctionBegin;
689e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF - Lapack routine is unavailable.");
690db4efbfdSBarry Smith #else
691db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
692db4efbfdSBarry Smith   PetscErrorCode ierr;
693c5df96a5SBarry Smith   PetscBLASInt   info,n;
694db4efbfdSBarry Smith 
695db4efbfdSBarry Smith   PetscFunctionBegin;
696c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
697db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
698a49dc2a2SStefano Zampini   if (A->spd) {
69900121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
7008b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
70100121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
702a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
703a49dc2a2SStefano Zampini   } else if (A->hermitian) {
704a49dc2a2SStefano Zampini     if (!mat->pivots) {
705a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
706a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
707a49dc2a2SStefano Zampini     }
708a49dc2a2SStefano Zampini     if (!mat->fwork) {
709a49dc2a2SStefano Zampini       PetscScalar dummy;
710a49dc2a2SStefano Zampini 
711a49dc2a2SStefano Zampini       mat->lfwork = -1;
71200121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
713a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
71400121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
715a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
716a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
717a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
718a49dc2a2SStefano Zampini     }
71900121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
720a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
72100121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
722a49dc2a2SStefano Zampini #endif
723a49dc2a2SStefano Zampini   } else { /* symmetric case */
724a49dc2a2SStefano Zampini     if (!mat->pivots) {
725a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
726a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
727a49dc2a2SStefano Zampini     }
728a49dc2a2SStefano Zampini     if (!mat->fwork) {
729a49dc2a2SStefano Zampini       PetscScalar dummy;
730a49dc2a2SStefano Zampini 
731a49dc2a2SStefano Zampini       mat->lfwork = -1;
73200121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
733a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
73400121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
735a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
736a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
737a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
738a49dc2a2SStefano Zampini     }
73900121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
740a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
74100121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
742a49dc2a2SStefano Zampini   }
743e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
7448208b9aeSStefano Zampini 
745db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
7468208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
747db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
748db4efbfdSBarry Smith   A->ops->solveadd          = MatSolveAdd_SeqDense;
749db4efbfdSBarry Smith   A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
750d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
7512205254eSKarl Rupp 
752f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
753f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
754f6224b95SHong Zhang 
755eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
756db4efbfdSBarry Smith #endif
757db4efbfdSBarry Smith   PetscFunctionReturn(0);
758db4efbfdSBarry Smith }
759db4efbfdSBarry Smith 
760db4efbfdSBarry Smith 
7610481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
762db4efbfdSBarry Smith {
763db4efbfdSBarry Smith   PetscErrorCode ierr;
764db4efbfdSBarry Smith   MatFactorInfo  info;
765db4efbfdSBarry Smith 
766db4efbfdSBarry Smith   PetscFunctionBegin;
767db4efbfdSBarry Smith   info.fill = 1.0;
7682205254eSKarl Rupp 
769c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
770719d5645SBarry Smith   ierr = MatCholeskyFactor_SeqDense(fact,0,&info);CHKERRQ(ierr);
771db4efbfdSBarry Smith   PetscFunctionReturn(0);
772db4efbfdSBarry Smith }
773db4efbfdSBarry Smith 
774e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
775db4efbfdSBarry Smith {
776db4efbfdSBarry Smith   PetscFunctionBegin;
777c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
7781bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
779719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
780bd443b22SStefano Zampini   fact->ops->solve                 = MatSolve_SeqDense;
781bd443b22SStefano Zampini   fact->ops->matsolve              = MatMatSolve_SeqDense;
782bd443b22SStefano Zampini   fact->ops->solvetranspose        = MatSolveTranspose_SeqDense;
783bd443b22SStefano Zampini   fact->ops->solveadd              = MatSolveAdd_SeqDense;
784bd443b22SStefano Zampini   fact->ops->solvetransposeadd     = MatSolveTransposeAdd_SeqDense;
785db4efbfdSBarry Smith   PetscFunctionReturn(0);
786db4efbfdSBarry Smith }
787db4efbfdSBarry Smith 
788e0877f53SBarry Smith static PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
789db4efbfdSBarry Smith {
790db4efbfdSBarry Smith   PetscFunctionBegin;
791b66fe19dSMatthew G Knepley   fact->preallocated           = PETSC_TRUE;
792c3ef05f6SHong Zhang   fact->assembled              = PETSC_TRUE;
793719d5645SBarry Smith   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
794bd443b22SStefano Zampini   fact->ops->solve             = MatSolve_SeqDense;
795bd443b22SStefano Zampini   fact->ops->matsolve          = MatMatSolve_SeqDense;
796bd443b22SStefano Zampini   fact->ops->solvetranspose    = MatSolveTranspose_SeqDense;
797bd443b22SStefano Zampini   fact->ops->solveadd          = MatSolveAdd_SeqDense;
798bd443b22SStefano Zampini   fact->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
799db4efbfdSBarry Smith   PetscFunctionReturn(0);
800db4efbfdSBarry Smith }
801db4efbfdSBarry Smith 
802cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
803db4efbfdSBarry Smith {
804db4efbfdSBarry Smith   PetscErrorCode ierr;
805db4efbfdSBarry Smith 
806db4efbfdSBarry Smith   PetscFunctionBegin;
807ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
808db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
809db4efbfdSBarry Smith   ierr = MatSetType(*fact,((PetscObject)A)->type_name);CHKERRQ(ierr);
810db4efbfdSBarry Smith   if (ftype == MAT_FACTOR_LU) {
811db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
812db4efbfdSBarry Smith   } else {
813db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
814db4efbfdSBarry Smith   }
815d5f3da31SBarry Smith   (*fact)->factortype = ftype;
81600c67f3bSHong Zhang 
81700c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
81800c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
819db4efbfdSBarry Smith   PetscFunctionReturn(0);
820db4efbfdSBarry Smith }
821db4efbfdSBarry Smith 
822289bc588SBarry Smith /* ------------------------------------------------------------------*/
823e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
824289bc588SBarry Smith {
825c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
826d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
827d9ca1df4SBarry Smith   const PetscScalar *b;
828dfbe8321SBarry Smith   PetscErrorCode    ierr;
829d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
830c5df96a5SBarry Smith   PetscBLASInt      o = 1,bm;
831289bc588SBarry Smith 
8323a40ed3dSBarry Smith   PetscFunctionBegin;
833422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
834c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
835289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
8363bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
8372dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
838289bc588SBarry Smith   }
8391ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
840d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
841b965ef7fSBarry Smith   its  = its*lits;
842e32f2f54SBarry 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);
843289bc588SBarry Smith   while (its--) {
844fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
845289bc588SBarry Smith       for (i=0; i<m; i++) {
8463bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
84755a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
848289bc588SBarry Smith       }
849289bc588SBarry Smith     }
850fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
851289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
8523bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
85355a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
854289bc588SBarry Smith       }
855289bc588SBarry Smith     }
856289bc588SBarry Smith   }
857d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
8581ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
8593a40ed3dSBarry Smith   PetscFunctionReturn(0);
860289bc588SBarry Smith }
861289bc588SBarry Smith 
862289bc588SBarry Smith /* -----------------------------------------------------------------*/
863cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
864289bc588SBarry Smith {
865c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
866d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
867d9ca1df4SBarry Smith   PetscScalar       *y;
868dfbe8321SBarry Smith   PetscErrorCode    ierr;
8690805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
870ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
8713a40ed3dSBarry Smith 
8723a40ed3dSBarry Smith   PetscFunctionBegin;
873c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
874c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
875d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8761ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8775ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8785ac36cfcSBarry Smith     PetscBLASInt i;
8795ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
8805ac36cfcSBarry Smith   } else {
8818b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
8825ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
8835ac36cfcSBarry Smith   }
884d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8851ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8863a40ed3dSBarry Smith   PetscFunctionReturn(0);
887289bc588SBarry Smith }
888800995b7SMatthew Knepley 
889cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
890289bc588SBarry Smith {
891c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
892d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
893dfbe8321SBarry Smith   PetscErrorCode    ierr;
8940805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
895d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
8963a40ed3dSBarry Smith 
8973a40ed3dSBarry Smith   PetscFunctionBegin;
898c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
899c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
900d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
9011ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9025ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
9035ac36cfcSBarry Smith     PetscBLASInt i;
9045ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
9055ac36cfcSBarry Smith   } else {
9068b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
9075ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
9085ac36cfcSBarry Smith   }
909d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
9101ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9113a40ed3dSBarry Smith   PetscFunctionReturn(0);
912289bc588SBarry Smith }
9136ee01492SSatish Balay 
914cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
915289bc588SBarry Smith {
916c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
917d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
918d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
919dfbe8321SBarry Smith   PetscErrorCode    ierr;
9200805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
9213a40ed3dSBarry Smith 
9223a40ed3dSBarry Smith   PetscFunctionBegin;
923c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
924c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
925d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
926600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
927d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
9281ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9298b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
930d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
9311ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
932dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
9333a40ed3dSBarry Smith   PetscFunctionReturn(0);
934289bc588SBarry Smith }
9356ee01492SSatish Balay 
936e0877f53SBarry Smith static PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
937289bc588SBarry Smith {
938c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
939d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
940d9ca1df4SBarry Smith   PetscScalar       *y;
941dfbe8321SBarry Smith   PetscErrorCode    ierr;
9420805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
94387828ca2SBarry Smith   PetscScalar       _DOne=1.0;
9443a40ed3dSBarry Smith 
9453a40ed3dSBarry Smith   PetscFunctionBegin;
946c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
947c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
948d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
949600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
950d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
9511ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9528b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
953d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
9541ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
955dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
9563a40ed3dSBarry Smith   PetscFunctionReturn(0);
957289bc588SBarry Smith }
958289bc588SBarry Smith 
959289bc588SBarry Smith /* -----------------------------------------------------------------*/
960e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
961289bc588SBarry Smith {
962c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
96387828ca2SBarry Smith   PetscScalar    *v;
9646849ba73SBarry Smith   PetscErrorCode ierr;
96513f74950SBarry Smith   PetscInt       i;
96667e560aaSBarry Smith 
9673a40ed3dSBarry Smith   PetscFunctionBegin;
968d0f46423SBarry Smith   *ncols = A->cmap->n;
969289bc588SBarry Smith   if (cols) {
970854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
971d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
972289bc588SBarry Smith   }
973289bc588SBarry Smith   if (vals) {
974854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
975289bc588SBarry Smith     v    = mat->v + row;
976d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
977289bc588SBarry Smith   }
9783a40ed3dSBarry Smith   PetscFunctionReturn(0);
979289bc588SBarry Smith }
9806ee01492SSatish Balay 
981e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
982289bc588SBarry Smith {
983dfbe8321SBarry Smith   PetscErrorCode ierr;
9846e111a19SKarl Rupp 
985606d414cSSatish Balay   PetscFunctionBegin;
986606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
987606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
9883a40ed3dSBarry Smith   PetscFunctionReturn(0);
989289bc588SBarry Smith }
990289bc588SBarry Smith /* ----------------------------------------------------------------*/
991e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
992289bc588SBarry Smith {
993c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
99413f74950SBarry Smith   PetscInt     i,j,idx=0;
995d6dfbf8fSBarry Smith 
9963a40ed3dSBarry Smith   PetscFunctionBegin;
997289bc588SBarry Smith   if (!mat->roworiented) {
998dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
999289bc588SBarry Smith       for (j=0; j<n; j++) {
1000cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
10012515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1002e32f2f54SBarry 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);
100358804f6dSBarry Smith #endif
1004289bc588SBarry Smith         for (i=0; i<m; i++) {
1005cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
10062515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1007e32f2f54SBarry 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);
100858804f6dSBarry Smith #endif
1009cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1010289bc588SBarry Smith         }
1011289bc588SBarry Smith       }
10123a40ed3dSBarry Smith     } else {
1013289bc588SBarry Smith       for (j=0; j<n; j++) {
1014cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
10152515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1016e32f2f54SBarry 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);
101758804f6dSBarry Smith #endif
1018289bc588SBarry Smith         for (i=0; i<m; i++) {
1019cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
10202515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1021e32f2f54SBarry 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);
102258804f6dSBarry Smith #endif
1023cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1024289bc588SBarry Smith         }
1025289bc588SBarry Smith       }
1026289bc588SBarry Smith     }
10273a40ed3dSBarry Smith   } else {
1028dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1029e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
1030cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
10312515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1032e32f2f54SBarry 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);
103358804f6dSBarry Smith #endif
1034e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
1035cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
10362515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1037e32f2f54SBarry 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);
103858804f6dSBarry Smith #endif
1039cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1040e8d4e0b9SBarry Smith         }
1041e8d4e0b9SBarry Smith       }
10423a40ed3dSBarry Smith     } else {
1043289bc588SBarry Smith       for (i=0; i<m; i++) {
1044cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
10452515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1046e32f2f54SBarry 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);
104758804f6dSBarry Smith #endif
1048289bc588SBarry Smith         for (j=0; j<n; j++) {
1049cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
10502515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1051e32f2f54SBarry 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);
105258804f6dSBarry Smith #endif
1053cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1054289bc588SBarry Smith         }
1055289bc588SBarry Smith       }
1056289bc588SBarry Smith     }
1057e8d4e0b9SBarry Smith   }
10583a40ed3dSBarry Smith   PetscFunctionReturn(0);
1059289bc588SBarry Smith }
1060e8d4e0b9SBarry Smith 
1061e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1062ae80bb75SLois Curfman McInnes {
1063ae80bb75SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
106413f74950SBarry Smith   PetscInt     i,j;
1065ae80bb75SLois Curfman McInnes 
10663a40ed3dSBarry Smith   PetscFunctionBegin;
1067ae80bb75SLois Curfman McInnes   /* row-oriented output */
1068ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
106997e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1070e32f2f54SBarry 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);
1071ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
10726f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1073e32f2f54SBarry 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);
107497e567efSBarry Smith       *v++ = mat->v[indexn[j]*mat->lda + indexm[i]];
1075ae80bb75SLois Curfman McInnes     }
1076ae80bb75SLois Curfman McInnes   }
10773a40ed3dSBarry Smith   PetscFunctionReturn(0);
1078ae80bb75SLois Curfman McInnes }
1079ae80bb75SLois Curfman McInnes 
1080289bc588SBarry Smith /* -----------------------------------------------------------------*/
1081289bc588SBarry Smith 
1082e0877f53SBarry Smith static PetscErrorCode MatLoad_SeqDense(Mat newmat,PetscViewer viewer)
1083aabbc4fbSShri Abhyankar {
1084aabbc4fbSShri Abhyankar   Mat_SeqDense   *a;
1085aabbc4fbSShri Abhyankar   PetscErrorCode ierr;
1086aabbc4fbSShri Abhyankar   PetscInt       *scols,i,j,nz,header[4];
1087aabbc4fbSShri Abhyankar   int            fd;
1088aabbc4fbSShri Abhyankar   PetscMPIInt    size;
1089aabbc4fbSShri Abhyankar   PetscInt       *rowlengths = 0,M,N,*cols,grows,gcols;
1090aabbc4fbSShri Abhyankar   PetscScalar    *vals,*svals,*v,*w;
1091ce94432eSBarry Smith   MPI_Comm       comm;
10927f489da9SVaclav Hapla   PetscBool      isbinary;
1093aabbc4fbSShri Abhyankar 
1094aabbc4fbSShri Abhyankar   PetscFunctionBegin;
10957f489da9SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
10967f489da9SVaclav 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);
10977f489da9SVaclav Hapla 
1098c98fd787SBarry Smith   /* force binary viewer to load .info file if it has not yet done so */
1099c98fd787SBarry Smith   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1100ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
1101aabbc4fbSShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1102aabbc4fbSShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"view must have one processor");
1103aabbc4fbSShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
1104aabbc4fbSShri Abhyankar   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
1105aabbc4fbSShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not matrix object");
1106aabbc4fbSShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
1107aabbc4fbSShri Abhyankar 
1108aabbc4fbSShri Abhyankar   /* set global size if not set already*/
1109aabbc4fbSShri Abhyankar   if (newmat->rmap->n < 0 && newmat->rmap->N < 0 && newmat->cmap->n < 0 && newmat->cmap->N < 0) {
1110aabbc4fbSShri Abhyankar     ierr = MatSetSizes(newmat,M,N,M,N);CHKERRQ(ierr);
1111aabbc4fbSShri Abhyankar   } else {
1112aabbc4fbSShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
1113aabbc4fbSShri Abhyankar     ierr = MatGetSize(newmat,&grows,&gcols);CHKERRQ(ierr);
1114aabbc4fbSShri 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);
1115aabbc4fbSShri Abhyankar   }
1116e6324fbbSBarry Smith   a = (Mat_SeqDense*)newmat->data;
1117e6324fbbSBarry Smith   if (!a->user_alloc) {
11180298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1119e6324fbbSBarry Smith   }
1120aabbc4fbSShri Abhyankar 
1121aabbc4fbSShri Abhyankar   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense */
1122aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
1123aabbc4fbSShri Abhyankar     v = a->v;
1124aabbc4fbSShri Abhyankar     /* Allocate some temp space to read in the values and then flip them
1125aabbc4fbSShri Abhyankar        from row major to column major */
1126854ce69bSBarry Smith     ierr = PetscMalloc1(M*N > 0 ? M*N : 1,&w);CHKERRQ(ierr);
1127aabbc4fbSShri Abhyankar     /* read in nonzero values */
1128aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,w,M*N,PETSC_SCALAR);CHKERRQ(ierr);
1129aabbc4fbSShri Abhyankar     /* now flip the values and store them in the matrix*/
1130aabbc4fbSShri Abhyankar     for (j=0; j<N; j++) {
1131aabbc4fbSShri Abhyankar       for (i=0; i<M; i++) {
1132aabbc4fbSShri Abhyankar         *v++ =w[i*N+j];
1133aabbc4fbSShri Abhyankar       }
1134aabbc4fbSShri Abhyankar     }
1135aabbc4fbSShri Abhyankar     ierr = PetscFree(w);CHKERRQ(ierr);
1136aabbc4fbSShri Abhyankar   } else {
1137aabbc4fbSShri Abhyankar     /* read row lengths */
1138854ce69bSBarry Smith     ierr = PetscMalloc1(M+1,&rowlengths);CHKERRQ(ierr);
1139aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
1140aabbc4fbSShri Abhyankar 
1141aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
1142aabbc4fbSShri Abhyankar     v = a->v;
1143aabbc4fbSShri Abhyankar 
1144aabbc4fbSShri Abhyankar     /* read column indices and nonzeros */
1145854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&scols);CHKERRQ(ierr);
1146aabbc4fbSShri Abhyankar     cols = scols;
1147aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT);CHKERRQ(ierr);
1148854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&svals);CHKERRQ(ierr);
1149aabbc4fbSShri Abhyankar     vals = svals;
1150aabbc4fbSShri Abhyankar     ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR);CHKERRQ(ierr);
1151aabbc4fbSShri Abhyankar 
1152aabbc4fbSShri Abhyankar     /* insert into matrix */
1153aabbc4fbSShri Abhyankar     for (i=0; i<M; i++) {
1154aabbc4fbSShri Abhyankar       for (j=0; j<rowlengths[i]; j++) v[i+M*scols[j]] = svals[j];
1155aabbc4fbSShri Abhyankar       svals += rowlengths[i]; scols += rowlengths[i];
1156aabbc4fbSShri Abhyankar     }
1157aabbc4fbSShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1158aabbc4fbSShri Abhyankar     ierr = PetscFree(cols);CHKERRQ(ierr);
1159aabbc4fbSShri Abhyankar     ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1160aabbc4fbSShri Abhyankar   }
1161aabbc4fbSShri Abhyankar   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1162aabbc4fbSShri Abhyankar   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1163aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1164aabbc4fbSShri Abhyankar }
1165aabbc4fbSShri Abhyankar 
11666849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1167289bc588SBarry Smith {
1168932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1169dfbe8321SBarry Smith   PetscErrorCode    ierr;
117013f74950SBarry Smith   PetscInt          i,j;
11712dcb1b2aSMatthew Knepley   const char        *name;
117287828ca2SBarry Smith   PetscScalar       *v;
1173f3ef73ceSBarry Smith   PetscViewerFormat format;
11745f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1175ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
11765f481a85SSatish Balay #endif
1177932b0c3eSLois Curfman McInnes 
11783a40ed3dSBarry Smith   PetscFunctionBegin;
1179b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1180456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
11813a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1182fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1183d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1184d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
118544cd7ae7SLois Curfman McInnes       v    = a->v + i;
118677431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1187d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1188aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1189329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
119057622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1191329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
119257622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
11936831982aSBarry Smith         }
119480cd9d93SLois Curfman McInnes #else
11956831982aSBarry Smith         if (*v) {
119657622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
11976831982aSBarry Smith         }
119880cd9d93SLois Curfman McInnes #endif
11991b807ce4Svictorle         v += a->lda;
120080cd9d93SLois Curfman McInnes       }
1201b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
120280cd9d93SLois Curfman McInnes     }
1203d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
12043a40ed3dSBarry Smith   } else {
1205d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1206aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
120747989497SBarry Smith     /* determine if matrix has all real values */
120847989497SBarry Smith     v = a->v;
1209d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1210ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
121147989497SBarry Smith     }
121247989497SBarry Smith #endif
1213fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
12143a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1215d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1216d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1217fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1218ffac6cdbSBarry Smith     }
1219ffac6cdbSBarry Smith 
1220d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1221932b0c3eSLois Curfman McInnes       v = a->v + i;
1222d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1223aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
122447989497SBarry Smith         if (allreal) {
1225c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
122647989497SBarry Smith         } else {
1227c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
122847989497SBarry Smith         }
1229289bc588SBarry Smith #else
1230c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1231289bc588SBarry Smith #endif
12321b807ce4Svictorle         v += a->lda;
1233289bc588SBarry Smith       }
1234b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1235289bc588SBarry Smith     }
1236fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1237b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1238ffac6cdbSBarry Smith     }
1239d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1240da3a660dSBarry Smith   }
1241b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
12423a40ed3dSBarry Smith   PetscFunctionReturn(0);
1243289bc588SBarry Smith }
1244289bc588SBarry Smith 
12456849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_Binary(Mat A,PetscViewer viewer)
1246932b0c3eSLois Curfman McInnes {
1247932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
12486849ba73SBarry Smith   PetscErrorCode    ierr;
124913f74950SBarry Smith   int               fd;
1250d0f46423SBarry Smith   PetscInt          ict,j,n = A->cmap->n,m = A->rmap->n,i,*col_lens,nz = m*n;
1251f4403165SShri Abhyankar   PetscScalar       *v,*anonz,*vals;
1252f4403165SShri Abhyankar   PetscViewerFormat format;
1253932b0c3eSLois Curfman McInnes 
12543a40ed3dSBarry Smith   PetscFunctionBegin;
1255b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
125690ace30eSBarry Smith 
1257f4403165SShri Abhyankar   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1258f4403165SShri Abhyankar   if (format == PETSC_VIEWER_NATIVE) {
1259f4403165SShri Abhyankar     /* store the matrix as a dense matrix */
1260785e854fSJed Brown     ierr = PetscMalloc1(4,&col_lens);CHKERRQ(ierr);
12612205254eSKarl Rupp 
1262f4403165SShri Abhyankar     col_lens[0] = MAT_FILE_CLASSID;
1263f4403165SShri Abhyankar     col_lens[1] = m;
1264f4403165SShri Abhyankar     col_lens[2] = n;
1265f4403165SShri Abhyankar     col_lens[3] = MATRIX_BINARY_FORMAT_DENSE;
12662205254eSKarl Rupp 
1267f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,col_lens,4,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1268f4403165SShri Abhyankar     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1269f4403165SShri Abhyankar 
1270f4403165SShri Abhyankar     /* write out matrix, by rows */
1271854ce69bSBarry Smith     ierr = PetscMalloc1(m*n+1,&vals);CHKERRQ(ierr);
1272f4403165SShri Abhyankar     v    = a->v;
1273f4403165SShri Abhyankar     for (j=0; j<n; j++) {
1274f4403165SShri Abhyankar       for (i=0; i<m; i++) {
1275f4403165SShri Abhyankar         vals[j + i*n] = *v++;
1276f4403165SShri Abhyankar       }
1277f4403165SShri Abhyankar     }
1278f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,vals,n*m,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1279f4403165SShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1280f4403165SShri Abhyankar   } else {
1281854ce69bSBarry Smith     ierr = PetscMalloc1(4+nz,&col_lens);CHKERRQ(ierr);
12822205254eSKarl Rupp 
12830700a824SBarry Smith     col_lens[0] = MAT_FILE_CLASSID;
1284932b0c3eSLois Curfman McInnes     col_lens[1] = m;
1285932b0c3eSLois Curfman McInnes     col_lens[2] = n;
1286932b0c3eSLois Curfman McInnes     col_lens[3] = nz;
1287932b0c3eSLois Curfman McInnes 
1288932b0c3eSLois Curfman McInnes     /* store lengths of each row and write (including header) to file */
1289932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) col_lens[4+i] = n;
12906f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,4+m,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1291932b0c3eSLois Curfman McInnes 
1292932b0c3eSLois Curfman McInnes     /* Possibly should write in smaller increments, not whole matrix at once? */
1293932b0c3eSLois Curfman McInnes     /* store column indices (zero start index) */
1294932b0c3eSLois Curfman McInnes     ict = 0;
1295932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1296932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) col_lens[ict++] = j;
1297932b0c3eSLois Curfman McInnes     }
12986f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
1299606d414cSSatish Balay     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1300932b0c3eSLois Curfman McInnes 
1301932b0c3eSLois Curfman McInnes     /* store nonzero values */
1302854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&anonz);CHKERRQ(ierr);
1303932b0c3eSLois Curfman McInnes     ict  = 0;
1304932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1305932b0c3eSLois Curfman McInnes       v = a->v + i;
1306932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) {
13071b807ce4Svictorle         anonz[ict++] = *v; v += a->lda;
1308932b0c3eSLois Curfman McInnes       }
1309932b0c3eSLois Curfman McInnes     }
13106f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,anonz,nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1311606d414cSSatish Balay     ierr = PetscFree(anonz);CHKERRQ(ierr);
1312f4403165SShri Abhyankar   }
13133a40ed3dSBarry Smith   PetscFunctionReturn(0);
1314932b0c3eSLois Curfman McInnes }
1315932b0c3eSLois Curfman McInnes 
13169804daf3SBarry Smith #include <petscdraw.h>
1317e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1318f1af5d2fSBarry Smith {
1319f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
1320f1af5d2fSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
13216849ba73SBarry Smith   PetscErrorCode    ierr;
1322383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1323383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
132487828ca2SBarry Smith   PetscScalar       *v = a->v;
1325b0a32e0cSBarry Smith   PetscViewer       viewer;
1326b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1327f3ef73ceSBarry Smith   PetscViewerFormat format;
1328f1af5d2fSBarry Smith 
1329f1af5d2fSBarry Smith   PetscFunctionBegin;
1330f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1331b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1332b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1333f1af5d2fSBarry Smith 
1334f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1335383922c3SLisandro Dalcin 
1336fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1337383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1338f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1339f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1340383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1341f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1342f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1343f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1344329f5518SBarry Smith         if (PetscRealPart(v[j*m+i]) >  0.) {
1345b0a32e0cSBarry Smith           color = PETSC_DRAW_RED;
1346329f5518SBarry Smith         } else if (PetscRealPart(v[j*m+i]) <  0.) {
1347b0a32e0cSBarry Smith           color = PETSC_DRAW_BLUE;
1348f1af5d2fSBarry Smith         } else {
1349f1af5d2fSBarry Smith           continue;
1350f1af5d2fSBarry Smith         }
1351b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1352f1af5d2fSBarry Smith       }
1353f1af5d2fSBarry Smith     }
1354383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1355f1af5d2fSBarry Smith   } else {
1356f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1357f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1358b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1359b05fc000SLisandro Dalcin     PetscDraw popup;
1360b05fc000SLisandro Dalcin 
1361f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1362f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1363f1af5d2fSBarry Smith     }
1364383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1365b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
136645f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1367383922c3SLisandro Dalcin 
1368383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1369f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1370f1af5d2fSBarry Smith       x_l = j;
1371f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1372f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1373f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1374f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1375b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1376b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1377f1af5d2fSBarry Smith       }
1378f1af5d2fSBarry Smith     }
1379383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1380f1af5d2fSBarry Smith   }
1381f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1382f1af5d2fSBarry Smith }
1383f1af5d2fSBarry Smith 
1384e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1385f1af5d2fSBarry Smith {
1386b0a32e0cSBarry Smith   PetscDraw      draw;
1387ace3abfcSBarry Smith   PetscBool      isnull;
1388329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1389dfbe8321SBarry Smith   PetscErrorCode ierr;
1390f1af5d2fSBarry Smith 
1391f1af5d2fSBarry Smith   PetscFunctionBegin;
1392b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1393b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1394abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1395f1af5d2fSBarry Smith 
1396d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1397f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1398b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1399832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1400b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
14010298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1402832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1403f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1404f1af5d2fSBarry Smith }
1405f1af5d2fSBarry Smith 
1406dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1407932b0c3eSLois Curfman McInnes {
1408dfbe8321SBarry Smith   PetscErrorCode ierr;
1409ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1410932b0c3eSLois Curfman McInnes 
14113a40ed3dSBarry Smith   PetscFunctionBegin;
1412251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1413251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1414251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
14150f5bd95cSBarry Smith 
1416c45a1595SBarry Smith   if (iascii) {
1417c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
14180f5bd95cSBarry Smith   } else if (isbinary) {
14193a40ed3dSBarry Smith     ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr);
1420f1af5d2fSBarry Smith   } else if (isdraw) {
1421f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1422932b0c3eSLois Curfman McInnes   }
14233a40ed3dSBarry Smith   PetscFunctionReturn(0);
1424932b0c3eSLois Curfman McInnes }
1425289bc588SBarry Smith 
1426d3042a70SBarry Smith static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar array[])
1427d3042a70SBarry Smith {
1428d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1429d3042a70SBarry Smith 
1430d3042a70SBarry Smith   PetscFunctionBegin;
1431d3042a70SBarry Smith   a->unplacedarray       = a->v;
1432d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1433d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1434d3042a70SBarry Smith   PetscFunctionReturn(0);
1435d3042a70SBarry Smith }
1436d3042a70SBarry Smith 
1437d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1438d3042a70SBarry Smith {
1439d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1440d3042a70SBarry Smith 
1441d3042a70SBarry Smith   PetscFunctionBegin;
1442d3042a70SBarry Smith   a->v             = a->unplacedarray;
1443d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1444d3042a70SBarry Smith   a->unplacedarray = NULL;
1445d3042a70SBarry Smith   PetscFunctionReturn(0);
1446d3042a70SBarry Smith }
1447d3042a70SBarry Smith 
1448e0877f53SBarry Smith static PetscErrorCode MatDestroy_SeqDense(Mat mat)
1449289bc588SBarry Smith {
1450ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1451dfbe8321SBarry Smith   PetscErrorCode ierr;
145290f02eecSBarry Smith 
14533a40ed3dSBarry Smith   PetscFunctionBegin;
1454aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1455d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1456a5a9c739SBarry Smith #endif
145705b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1458a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1459abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
14606857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1461bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1462dbd8c25aSHong Zhang 
1463dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
1464*49a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1465bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
1466d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1467d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
1468bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
14698baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
14708baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
14718baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
14728baccfbdSHong Zhang #endif
1473bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
1474bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1475bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1476bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1477abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatPtAP_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14783bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14793bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14803bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
148186aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
148286aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
14833a40ed3dSBarry Smith   PetscFunctionReturn(0);
1484289bc588SBarry Smith }
1485289bc588SBarry Smith 
1486e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1487289bc588SBarry Smith {
1488c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
14896849ba73SBarry Smith   PetscErrorCode ierr;
149013f74950SBarry Smith   PetscInt       k,j,m,n,M;
149187828ca2SBarry Smith   PetscScalar    *v,tmp;
149248b35521SBarry Smith 
14933a40ed3dSBarry Smith   PetscFunctionBegin;
1494d0f46423SBarry Smith   v = mat->v; m = A->rmap->n; M = mat->lda; n = A->cmap->n;
14952847e3fdSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX && m == n) { /* in place transpose */
1496d3e5ee88SLois Curfman McInnes     for (j=0; j<m; j++) {
1497289bc588SBarry Smith       for (k=0; k<j; k++) {
14981b807ce4Svictorle         tmp        = v[j + k*M];
14991b807ce4Svictorle         v[j + k*M] = v[k + j*M];
15001b807ce4Svictorle         v[k + j*M] = tmp;
1501289bc588SBarry Smith       }
1502289bc588SBarry Smith     }
15033a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1504d3e5ee88SLois Curfman McInnes     Mat          tmat;
1505ec8511deSBarry Smith     Mat_SeqDense *tmatd;
150687828ca2SBarry Smith     PetscScalar  *v2;
1507af36a384SStefano Zampini     PetscInt     M2;
1508ea709b57SSatish Balay 
15092847e3fdSStefano Zampini     if (reuse != MAT_REUSE_MATRIX) {
1510ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1511d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
15127adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
15130298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1514fc4dec0aSBarry Smith     } else {
1515fc4dec0aSBarry Smith       tmat = *matout;
1516fc4dec0aSBarry Smith     }
1517ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1518af36a384SStefano Zampini     v = mat->v; v2 = tmatd->v; M2 = tmatd->lda;
1519d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1520af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1521d3e5ee88SLois Curfman McInnes     }
15226d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15236d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15242847e3fdSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) *matout = tmat;
15252847e3fdSStefano Zampini     else {
15262847e3fdSStefano Zampini       ierr = MatHeaderMerge(A,&tmat);CHKERRQ(ierr);
15272847e3fdSStefano Zampini     }
152848b35521SBarry Smith   }
15293a40ed3dSBarry Smith   PetscFunctionReturn(0);
1530289bc588SBarry Smith }
1531289bc588SBarry Smith 
1532e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1533289bc588SBarry Smith {
1534c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat1 = (Mat_SeqDense*)A1->data;
1535c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat2 = (Mat_SeqDense*)A2->data;
153613f74950SBarry Smith   PetscInt     i,j;
1537a2ea699eSBarry Smith   PetscScalar  *v1,*v2;
15389ea5d5aeSSatish Balay 
15393a40ed3dSBarry Smith   PetscFunctionBegin;
1540d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1541d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1542d0f46423SBarry Smith   for (i=0; i<A1->rmap->n; i++) {
15431b807ce4Svictorle     v1 = mat1->v+i; v2 = mat2->v+i;
1544d0f46423SBarry Smith     for (j=0; j<A1->cmap->n; j++) {
15453a40ed3dSBarry Smith       if (*v1 != *v2) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
15461b807ce4Svictorle       v1 += mat1->lda; v2 += mat2->lda;
15471b807ce4Svictorle     }
1548289bc588SBarry Smith   }
154977c4ece6SBarry Smith   *flg = PETSC_TRUE;
15503a40ed3dSBarry Smith   PetscFunctionReturn(0);
1551289bc588SBarry Smith }
1552289bc588SBarry Smith 
1553e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1554289bc588SBarry Smith {
1555c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
1556dfbe8321SBarry Smith   PetscErrorCode ierr;
155713f74950SBarry Smith   PetscInt       i,n,len;
155887828ca2SBarry Smith   PetscScalar    *x,zero = 0.0;
155944cd7ae7SLois Curfman McInnes 
15603a40ed3dSBarry Smith   PetscFunctionBegin;
15612dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
15627a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
15631ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1564d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1565e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
156644cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
15671b807ce4Svictorle     x[i] = mat->v[i*mat->lda + i];
1568289bc588SBarry Smith   }
15691ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
15703a40ed3dSBarry Smith   PetscFunctionReturn(0);
1571289bc588SBarry Smith }
1572289bc588SBarry Smith 
1573e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1574289bc588SBarry Smith {
1575c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1576f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1577f1ceaac6SMatthew G. Knepley   PetscScalar       x,*v;
1578dfbe8321SBarry Smith   PetscErrorCode    ierr;
1579d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
158055659b69SBarry Smith 
15813a40ed3dSBarry Smith   PetscFunctionBegin;
158228988994SBarry Smith   if (ll) {
15837a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1584f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1585e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1586da3a660dSBarry Smith     for (i=0; i<m; i++) {
1587da3a660dSBarry Smith       x = l[i];
1588da3a660dSBarry Smith       v = mat->v + i;
1589b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1590da3a660dSBarry Smith     }
1591f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1592eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1593da3a660dSBarry Smith   }
159428988994SBarry Smith   if (rr) {
15957a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1596f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1597e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1598da3a660dSBarry Smith     for (i=0; i<n; i++) {
1599da3a660dSBarry Smith       x = r[i];
1600b43bac26SStefano Zampini       v = mat->v + i*mat->lda;
16012205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1602da3a660dSBarry Smith     }
1603f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1604eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1605da3a660dSBarry Smith   }
16063a40ed3dSBarry Smith   PetscFunctionReturn(0);
1607289bc588SBarry Smith }
1608289bc588SBarry Smith 
1609e0877f53SBarry Smith static PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1610289bc588SBarry Smith {
1611c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
161287828ca2SBarry Smith   PetscScalar    *v   = mat->v;
1613329f5518SBarry Smith   PetscReal      sum  = 0.0;
1614d0f46423SBarry Smith   PetscInt       lda  =mat->lda,m=A->rmap->n,i,j;
1615efee365bSSatish Balay   PetscErrorCode ierr;
161655659b69SBarry Smith 
16173a40ed3dSBarry Smith   PetscFunctionBegin;
1618289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1619a5ce6ee0Svictorle     if (lda>m) {
1620d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1621a5ce6ee0Svictorle         v = mat->v+j*lda;
1622a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1623a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1624a5ce6ee0Svictorle         }
1625a5ce6ee0Svictorle       }
1626a5ce6ee0Svictorle     } else {
1627570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1628570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1629570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1630570b7f6dSBarry Smith     }
1631570b7f6dSBarry Smith #else
1632d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1633329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1634289bc588SBarry Smith       }
1635a5ce6ee0Svictorle     }
16368f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1637570b7f6dSBarry Smith #endif
1638dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16393a40ed3dSBarry Smith   } else if (type == NORM_1) {
1640064f8208SBarry Smith     *nrm = 0.0;
1641d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
16421b807ce4Svictorle       v   = mat->v + j*mat->lda;
1643289bc588SBarry Smith       sum = 0.0;
1644d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
164533a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1646289bc588SBarry Smith       }
1647064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1648289bc588SBarry Smith     }
1649eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16503a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1651064f8208SBarry Smith     *nrm = 0.0;
1652d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1653289bc588SBarry Smith       v   = mat->v + j;
1654289bc588SBarry Smith       sum = 0.0;
1655d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
16561b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1657289bc588SBarry Smith       }
1658064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1659289bc588SBarry Smith     }
1660eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1661e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
16623a40ed3dSBarry Smith   PetscFunctionReturn(0);
1663289bc588SBarry Smith }
1664289bc588SBarry Smith 
1665e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1666289bc588SBarry Smith {
1667c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
166863ba0a88SBarry Smith   PetscErrorCode ierr;
166967e560aaSBarry Smith 
16703a40ed3dSBarry Smith   PetscFunctionBegin;
1671b5a2b587SKris Buschelman   switch (op) {
1672b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
16734e0d8c25SBarry Smith     aij->roworiented = flg;
1674b5a2b587SKris Buschelman     break;
1675512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1676b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
16773971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
16784e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
167913fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1680b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1681b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
16820f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
16835021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
16845021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
16855021d80fSJed Brown     break;
16865021d80fSJed Brown   case MAT_SPD:
168777e54ba9SKris Buschelman   case MAT_SYMMETRIC:
168877e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
16899a4540c5SBarry Smith   case MAT_HERMITIAN:
16909a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
16915021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
169277e54ba9SKris Buschelman     break;
1693b5a2b587SKris Buschelman   default:
1694e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
16953a40ed3dSBarry Smith   }
16963a40ed3dSBarry Smith   PetscFunctionReturn(0);
1697289bc588SBarry Smith }
1698289bc588SBarry Smith 
1699e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
17006f0a148fSBarry Smith {
1701ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
17026849ba73SBarry Smith   PetscErrorCode ierr;
1703d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
17043a40ed3dSBarry Smith 
17053a40ed3dSBarry Smith   PetscFunctionBegin;
1706a5ce6ee0Svictorle   if (lda>m) {
1707d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1708a5ce6ee0Svictorle       ierr = PetscMemzero(l->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr);
1709a5ce6ee0Svictorle     }
1710a5ce6ee0Svictorle   } else {
1711d0f46423SBarry Smith     ierr = PetscMemzero(l->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
1712a5ce6ee0Svictorle   }
17133a40ed3dSBarry Smith   PetscFunctionReturn(0);
17146f0a148fSBarry Smith }
17156f0a148fSBarry Smith 
1716e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
17176f0a148fSBarry Smith {
171897b48c8fSBarry Smith   PetscErrorCode    ierr;
1719ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1720b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
172197b48c8fSBarry Smith   PetscScalar       *slot,*bb;
172297b48c8fSBarry Smith   const PetscScalar *xx;
172355659b69SBarry Smith 
17243a40ed3dSBarry Smith   PetscFunctionBegin;
1725b9679d65SBarry Smith #if defined(PETSC_USE_DEBUG)
1726b9679d65SBarry Smith   for (i=0; i<N; i++) {
1727b9679d65SBarry Smith     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1728b9679d65SBarry 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);
1729b9679d65SBarry Smith   }
1730b9679d65SBarry Smith #endif
1731b9679d65SBarry Smith 
173297b48c8fSBarry Smith   /* fix right hand side if needed */
173397b48c8fSBarry Smith   if (x && b) {
173497b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
173597b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
17362205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
173797b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
173897b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
173997b48c8fSBarry Smith   }
174097b48c8fSBarry Smith 
17416f0a148fSBarry Smith   for (i=0; i<N; i++) {
17426f0a148fSBarry Smith     slot = l->v + rows[i];
1743b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
17446f0a148fSBarry Smith   }
1745f4df32b1SMatthew Knepley   if (diag != 0.0) {
1746b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
17476f0a148fSBarry Smith     for (i=0; i<N; i++) {
1748b9679d65SBarry Smith       slot  = l->v + (m+1)*rows[i];
1749f4df32b1SMatthew Knepley       *slot = diag;
17506f0a148fSBarry Smith     }
17516f0a148fSBarry Smith   }
17523a40ed3dSBarry Smith   PetscFunctionReturn(0);
17536f0a148fSBarry Smith }
1754557bce09SLois Curfman McInnes 
1755*49a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
1756*49a6ff4bSBarry Smith {
1757*49a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
1758*49a6ff4bSBarry Smith 
1759*49a6ff4bSBarry Smith   PetscFunctionBegin;
1760*49a6ff4bSBarry Smith   *lda = mat->lda;
1761*49a6ff4bSBarry Smith   PetscFunctionReturn(0);
1762*49a6ff4bSBarry Smith }
1763*49a6ff4bSBarry Smith 
1764e0877f53SBarry Smith static PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar *array[])
176564e87e97SBarry Smith {
1766c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
17673a40ed3dSBarry Smith 
17683a40ed3dSBarry Smith   PetscFunctionBegin;
1769e32f2f54SBarry 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");
177064e87e97SBarry Smith   *array = mat->v;
17713a40ed3dSBarry Smith   PetscFunctionReturn(0);
177264e87e97SBarry Smith }
17730754003eSLois Curfman McInnes 
1774e0877f53SBarry Smith static PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar *array[])
1775ff14e315SSatish Balay {
17763a40ed3dSBarry Smith   PetscFunctionBegin;
17773a40ed3dSBarry Smith   PetscFunctionReturn(0);
1778ff14e315SSatish Balay }
17790754003eSLois Curfman McInnes 
1780dec5eb66SMatthew G Knepley /*@C
1781*49a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
1782*49a6ff4bSBarry Smith 
1783*49a6ff4bSBarry Smith    Logically Collective on Mat
1784*49a6ff4bSBarry Smith 
1785*49a6ff4bSBarry Smith    Input Parameter:
1786*49a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
1787*49a6ff4bSBarry Smith 
1788*49a6ff4bSBarry Smith    Output Parameter:
1789*49a6ff4bSBarry Smith .   lda - the leading dimension
1790*49a6ff4bSBarry Smith 
1791*49a6ff4bSBarry Smith    Level: intermediate
1792*49a6ff4bSBarry Smith 
1793*49a6ff4bSBarry Smith .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatSeqDenseSetLDA()
1794*49a6ff4bSBarry Smith @*/
1795*49a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
1796*49a6ff4bSBarry Smith {
1797*49a6ff4bSBarry Smith   PetscErrorCode ierr;
1798*49a6ff4bSBarry Smith 
1799*49a6ff4bSBarry Smith   PetscFunctionBegin;
1800*49a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
1801*49a6ff4bSBarry Smith   PetscFunctionReturn(0);
1802*49a6ff4bSBarry Smith }
1803*49a6ff4bSBarry Smith 
1804*49a6ff4bSBarry Smith /*@C
18058c778c55SBarry Smith    MatDenseGetArray - gives access to the array where the data for a SeqDense matrix is stored
180673a71a0fSBarry Smith 
18078572280aSBarry Smith    Logically Collective on Mat
180873a71a0fSBarry Smith 
180973a71a0fSBarry Smith    Input Parameter:
1810579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
181173a71a0fSBarry Smith 
181273a71a0fSBarry Smith    Output Parameter:
181373a71a0fSBarry Smith .   array - pointer to the data
181473a71a0fSBarry Smith 
181573a71a0fSBarry Smith    Level: intermediate
181673a71a0fSBarry Smith 
18178572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
181873a71a0fSBarry Smith @*/
18198c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
182073a71a0fSBarry Smith {
182173a71a0fSBarry Smith   PetscErrorCode ierr;
182273a71a0fSBarry Smith 
182373a71a0fSBarry Smith   PetscFunctionBegin;
18248c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
182573a71a0fSBarry Smith   PetscFunctionReturn(0);
182673a71a0fSBarry Smith }
182773a71a0fSBarry Smith 
1828dec5eb66SMatthew G Knepley /*@C
1829579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
183073a71a0fSBarry Smith 
18318572280aSBarry Smith    Logically Collective on Mat
18328572280aSBarry Smith 
18338572280aSBarry Smith    Input Parameters:
18348572280aSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
18358572280aSBarry Smith .  array - pointer to the data
18368572280aSBarry Smith 
18378572280aSBarry Smith    Level: intermediate
18388572280aSBarry Smith 
18398572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
18408572280aSBarry Smith @*/
18418572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
18428572280aSBarry Smith {
18438572280aSBarry Smith   PetscErrorCode ierr;
18448572280aSBarry Smith 
18458572280aSBarry Smith   PetscFunctionBegin;
18468572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
18478572280aSBarry Smith   if (array) *array = NULL;
18488572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
18498572280aSBarry Smith   PetscFunctionReturn(0);
18508572280aSBarry Smith }
18518572280aSBarry Smith 
18528572280aSBarry Smith /*@C
18538572280aSBarry Smith    MatDenseGetArrayRead - gives access to the array where the data for a SeqDense matrix is stored
18548572280aSBarry Smith 
18558572280aSBarry Smith    Not Collective
18568572280aSBarry Smith 
18578572280aSBarry Smith    Input Parameter:
18588572280aSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
18598572280aSBarry Smith 
18608572280aSBarry Smith    Output Parameter:
18618572280aSBarry Smith .   array - pointer to the data
18628572280aSBarry Smith 
18638572280aSBarry Smith    Level: intermediate
18648572280aSBarry Smith 
18658572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArray(), MatDenseRestoreArrayRead()
18668572280aSBarry Smith @*/
18678572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
18688572280aSBarry Smith {
18698572280aSBarry Smith   PetscErrorCode ierr;
18708572280aSBarry Smith 
18718572280aSBarry Smith   PetscFunctionBegin;
18728572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
18738572280aSBarry Smith   PetscFunctionReturn(0);
18748572280aSBarry Smith }
18758572280aSBarry Smith 
18768572280aSBarry Smith /*@C
18778572280aSBarry Smith    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
18788572280aSBarry Smith 
187973a71a0fSBarry Smith    Not Collective
188073a71a0fSBarry Smith 
188173a71a0fSBarry Smith    Input Parameters:
1882579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
188373a71a0fSBarry Smith .  array - pointer to the data
188473a71a0fSBarry Smith 
188573a71a0fSBarry Smith    Level: intermediate
188673a71a0fSBarry Smith 
18878572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArray()
188873a71a0fSBarry Smith @*/
18898572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
189073a71a0fSBarry Smith {
189173a71a0fSBarry Smith   PetscErrorCode ierr;
189273a71a0fSBarry Smith 
189373a71a0fSBarry Smith   PetscFunctionBegin;
18948572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
18958572280aSBarry Smith   if (array) *array = NULL;
189673a71a0fSBarry Smith   PetscFunctionReturn(0);
189773a71a0fSBarry Smith }
189873a71a0fSBarry Smith 
18997dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
19000754003eSLois Curfman McInnes {
1901c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
19026849ba73SBarry Smith   PetscErrorCode ierr;
19035d0c19d7SBarry Smith   PetscInt       i,j,nrows,ncols;
19045d0c19d7SBarry Smith   const PetscInt *irow,*icol;
190587828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
19060754003eSLois Curfman McInnes   Mat            newmat;
19070754003eSLois Curfman McInnes 
19083a40ed3dSBarry Smith   PetscFunctionBegin;
190978b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
191078b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1911e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1912e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
19130754003eSLois Curfman McInnes 
1914182d2002SSatish Balay   /* Check submatrixcall */
1915182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
191613f74950SBarry Smith     PetscInt n_cols,n_rows;
1917182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
191821a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
1919f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
1920c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
192121a2c019SBarry Smith     }
1922182d2002SSatish Balay     newmat = *B;
1923182d2002SSatish Balay   } else {
19240754003eSLois Curfman McInnes     /* Create and fill new matrix */
1925ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
1926f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
19277adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
19280298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1929182d2002SSatish Balay   }
1930182d2002SSatish Balay 
1931182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1932182d2002SSatish Balay   bv = ((Mat_SeqDense*)newmat->data)->v;
1933182d2002SSatish Balay 
1934182d2002SSatish Balay   for (i=0; i<ncols; i++) {
19356de62eeeSBarry Smith     av = v + mat->lda*icol[i];
19362205254eSKarl Rupp     for (j=0; j<nrows; j++) *bv++ = av[irow[j]];
19370754003eSLois Curfman McInnes   }
1938182d2002SSatish Balay 
1939182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
19406d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19416d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19420754003eSLois Curfman McInnes 
19430754003eSLois Curfman McInnes   /* Free work space */
194478b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
194578b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1946182d2002SSatish Balay   *B   = newmat;
19473a40ed3dSBarry Smith   PetscFunctionReturn(0);
19480754003eSLois Curfman McInnes }
19490754003eSLois Curfman McInnes 
19507dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1951905e6a2fSBarry Smith {
19526849ba73SBarry Smith   PetscErrorCode ierr;
195313f74950SBarry Smith   PetscInt       i;
1954905e6a2fSBarry Smith 
19553a40ed3dSBarry Smith   PetscFunctionBegin;
1956905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1957df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
1958905e6a2fSBarry Smith   }
1959905e6a2fSBarry Smith 
1960905e6a2fSBarry Smith   for (i=0; i<n; i++) {
19617dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1962905e6a2fSBarry Smith   }
19633a40ed3dSBarry Smith   PetscFunctionReturn(0);
1964905e6a2fSBarry Smith }
1965905e6a2fSBarry Smith 
1966e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
1967c0aa2d19SHong Zhang {
1968c0aa2d19SHong Zhang   PetscFunctionBegin;
1969c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1970c0aa2d19SHong Zhang }
1971c0aa2d19SHong Zhang 
1972e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
1973c0aa2d19SHong Zhang {
1974c0aa2d19SHong Zhang   PetscFunctionBegin;
1975c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1976c0aa2d19SHong Zhang }
1977c0aa2d19SHong Zhang 
1978e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
19794b0e389bSBarry Smith {
19804b0e389bSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
19816849ba73SBarry Smith   PetscErrorCode ierr;
1982d0f46423SBarry Smith   PetscInt       lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
19833a40ed3dSBarry Smith 
19843a40ed3dSBarry Smith   PetscFunctionBegin;
198533f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
198633f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
1987cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
19883a40ed3dSBarry Smith     PetscFunctionReturn(0);
19893a40ed3dSBarry Smith   }
1990e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
1991a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
19920dbb7854Svictorle     for (j=0; j<n; j++) {
1993a5ce6ee0Svictorle       ierr = PetscMemcpy(b->v+j*lda2,a->v+j*lda1,m*sizeof(PetscScalar));CHKERRQ(ierr);
1994a5ce6ee0Svictorle     }
1995a5ce6ee0Svictorle   } else {
1996d0f46423SBarry Smith     ierr = PetscMemcpy(b->v,a->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
1997a5ce6ee0Svictorle   }
1998cdc753b6SBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
1999273d9f13SBarry Smith   PetscFunctionReturn(0);
2000273d9f13SBarry Smith }
2001273d9f13SBarry Smith 
2002e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
2003273d9f13SBarry Smith {
2004dfbe8321SBarry Smith   PetscErrorCode ierr;
2005273d9f13SBarry Smith 
2006273d9f13SBarry Smith   PetscFunctionBegin;
2007273d9f13SBarry Smith   ierr =  MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
20083a40ed3dSBarry Smith   PetscFunctionReturn(0);
20094b0e389bSBarry Smith }
20104b0e389bSBarry Smith 
2011ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2012ba337c44SJed Brown {
2013ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
2014ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
2015ba337c44SJed Brown   PetscScalar  *aa = a->v;
2016ba337c44SJed Brown 
2017ba337c44SJed Brown   PetscFunctionBegin;
2018ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2019ba337c44SJed Brown   PetscFunctionReturn(0);
2020ba337c44SJed Brown }
2021ba337c44SJed Brown 
2022ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2023ba337c44SJed Brown {
2024ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
2025ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
2026ba337c44SJed Brown   PetscScalar  *aa = a->v;
2027ba337c44SJed Brown 
2028ba337c44SJed Brown   PetscFunctionBegin;
2029ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2030ba337c44SJed Brown   PetscFunctionReturn(0);
2031ba337c44SJed Brown }
2032ba337c44SJed Brown 
2033ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2034ba337c44SJed Brown {
2035ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
2036ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
2037ba337c44SJed Brown   PetscScalar  *aa = a->v;
2038ba337c44SJed Brown 
2039ba337c44SJed Brown   PetscFunctionBegin;
2040ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
2041ba337c44SJed Brown   PetscFunctionReturn(0);
2042ba337c44SJed Brown }
2043284134d9SBarry Smith 
2044a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
2045150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
2046a9fe9ddaSSatish Balay {
2047a9fe9ddaSSatish Balay   PetscErrorCode ierr;
2048a9fe9ddaSSatish Balay 
2049a9fe9ddaSSatish Balay   PetscFunctionBegin;
2050a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
20513ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2052a9fe9ddaSSatish Balay     ierr = MatMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
20533ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2054a9fe9ddaSSatish Balay   }
20553ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2056a9fe9ddaSSatish Balay   ierr = MatMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
20573ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2058a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2059a9fe9ddaSSatish Balay }
2060a9fe9ddaSSatish Balay 
2061a9fe9ddaSSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
2062a9fe9ddaSSatish Balay {
2063ee16a9a1SHong Zhang   PetscErrorCode ierr;
2064d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
2065ee16a9a1SHong Zhang   Mat            Cmat;
2066a9fe9ddaSSatish Balay 
2067ee16a9a1SHong Zhang   PetscFunctionBegin;
2068e32f2f54SBarry 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);
2069ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
2070ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
2071ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
20720298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
2073d73949e8SHong Zhang 
2074ee16a9a1SHong Zhang   *C = Cmat;
2075ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2076ee16a9a1SHong Zhang }
2077a9fe9ddaSSatish Balay 
2078a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2079a9fe9ddaSSatish Balay {
2080a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2081a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2082a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
20830805154bSBarry Smith   PetscBLASInt   m,n,k;
2084a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
2085c5df96a5SBarry Smith   PetscErrorCode ierr;
2086fd4e9aacSBarry Smith   PetscBool      flg;
2087a9fe9ddaSSatish Balay 
2088a9fe9ddaSSatish Balay   PetscFunctionBegin;
2089fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQDENSE,&flg);CHKERRQ(ierr);
2090fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Second matrix must be dense");
2091fd4e9aacSBarry Smith 
2092fd4e9aacSBarry Smith   /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/
2093fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
2094fd4e9aacSBarry Smith   if (flg) {
2095fd4e9aacSBarry Smith     C->ops->matmultnumeric = MatMatMultNumeric_SeqAIJ_SeqDense;
2096fd4e9aacSBarry Smith     ierr = (*C->ops->matmultnumeric)(A,B,C);CHKERRQ(ierr);
2097fd4e9aacSBarry Smith     PetscFunctionReturn(0);
2098fd4e9aacSBarry Smith   }
2099fd4e9aacSBarry Smith 
2100fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&flg);CHKERRQ(ierr);
2101fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"First matrix must be dense");
21028208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
21038208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2104c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
210549d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
21065ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2107a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2108a9fe9ddaSSatish Balay }
2109a9fe9ddaSSatish Balay 
211069f65d41SStefano Zampini PetscErrorCode MatMatTransposeMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
211169f65d41SStefano Zampini {
211269f65d41SStefano Zampini   PetscErrorCode ierr;
211369f65d41SStefano Zampini 
211469f65d41SStefano Zampini   PetscFunctionBegin;
211569f65d41SStefano Zampini   if (scall == MAT_INITIAL_MATRIX) {
211669f65d41SStefano Zampini     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
211769f65d41SStefano Zampini     ierr = MatMatTransposeMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
211869f65d41SStefano Zampini     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
211969f65d41SStefano Zampini   }
212069f65d41SStefano Zampini   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
212169f65d41SStefano Zampini   ierr = MatMatTransposeMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
212269f65d41SStefano Zampini   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
212369f65d41SStefano Zampini   PetscFunctionReturn(0);
212469f65d41SStefano Zampini }
212569f65d41SStefano Zampini 
212669f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
212769f65d41SStefano Zampini {
212869f65d41SStefano Zampini   PetscErrorCode ierr;
212969f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
213069f65d41SStefano Zampini   Mat            Cmat;
213169f65d41SStefano Zampini 
213269f65d41SStefano Zampini   PetscFunctionBegin;
213369f65d41SStefano 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);
213469f65d41SStefano Zampini   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
213569f65d41SStefano Zampini   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
213669f65d41SStefano Zampini   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
213769f65d41SStefano Zampini   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
213869f65d41SStefano Zampini 
213969f65d41SStefano Zampini   Cmat->assembled = PETSC_TRUE;
214069f65d41SStefano Zampini 
214169f65d41SStefano Zampini   *C = Cmat;
214269f65d41SStefano Zampini   PetscFunctionReturn(0);
214369f65d41SStefano Zampini }
214469f65d41SStefano Zampini 
214569f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
214669f65d41SStefano Zampini {
214769f65d41SStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
214869f65d41SStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
214969f65d41SStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
215069f65d41SStefano Zampini   PetscBLASInt   m,n,k;
215169f65d41SStefano Zampini   PetscScalar    _DOne=1.0,_DZero=0.0;
215269f65d41SStefano Zampini   PetscErrorCode ierr;
215369f65d41SStefano Zampini 
215469f65d41SStefano Zampini   PetscFunctionBegin;
215549d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
215649d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
215769f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
215849d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
215969f65d41SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
216069f65d41SStefano Zampini   PetscFunctionReturn(0);
216169f65d41SStefano Zampini }
216269f65d41SStefano Zampini 
216375648e8dSHong Zhang PetscErrorCode MatTransposeMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
2164a9fe9ddaSSatish Balay {
2165a9fe9ddaSSatish Balay   PetscErrorCode ierr;
2166a9fe9ddaSSatish Balay 
2167a9fe9ddaSSatish Balay   PetscFunctionBegin;
2168a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
21693ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
217075648e8dSHong Zhang     ierr = MatTransposeMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
21713ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2172a9fe9ddaSSatish Balay   }
21733ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
217475648e8dSHong Zhang   ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
21753ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2176a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2177a9fe9ddaSSatish Balay }
2178a9fe9ddaSSatish Balay 
217975648e8dSHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
2180a9fe9ddaSSatish Balay {
2181ee16a9a1SHong Zhang   PetscErrorCode ierr;
2182d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
2183ee16a9a1SHong Zhang   Mat            Cmat;
2184a9fe9ddaSSatish Balay 
2185ee16a9a1SHong Zhang   PetscFunctionBegin;
2186e32f2f54SBarry 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);
2187ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
2188ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
2189ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
21900298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
21912205254eSKarl Rupp 
2192ee16a9a1SHong Zhang   Cmat->assembled = PETSC_TRUE;
21932205254eSKarl Rupp 
2194ee16a9a1SHong Zhang   *C = Cmat;
2195ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2196ee16a9a1SHong Zhang }
2197a9fe9ddaSSatish Balay 
219875648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2199a9fe9ddaSSatish Balay {
2200a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2201a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2202a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
22030805154bSBarry Smith   PetscBLASInt   m,n,k;
2204a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
2205c5df96a5SBarry Smith   PetscErrorCode ierr;
2206a9fe9ddaSSatish Balay 
2207a9fe9ddaSSatish Balay   PetscFunctionBegin;
22088208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
22098208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2210c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
221149d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
22125ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2213a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2214a9fe9ddaSSatish Balay }
2215985db425SBarry Smith 
2216e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2217985db425SBarry Smith {
2218985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2219985db425SBarry Smith   PetscErrorCode ierr;
2220d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
2221985db425SBarry Smith   PetscScalar    *x;
2222985db425SBarry Smith   MatScalar      *aa = a->v;
2223985db425SBarry Smith 
2224985db425SBarry Smith   PetscFunctionBegin;
2225e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2226985db425SBarry Smith 
2227985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2228985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2229985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2230e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2231985db425SBarry Smith   for (i=0; i<m; i++) {
2232985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2233985db425SBarry Smith     for (j=1; j<n; j++) {
2234985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
2235985db425SBarry Smith     }
2236985db425SBarry Smith   }
2237985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2238985db425SBarry Smith   PetscFunctionReturn(0);
2239985db425SBarry Smith }
2240985db425SBarry Smith 
2241e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2242985db425SBarry Smith {
2243985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2244985db425SBarry Smith   PetscErrorCode ierr;
2245d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
2246985db425SBarry Smith   PetscScalar    *x;
2247985db425SBarry Smith   PetscReal      atmp;
2248985db425SBarry Smith   MatScalar      *aa = a->v;
2249985db425SBarry Smith 
2250985db425SBarry Smith   PetscFunctionBegin;
2251e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2252985db425SBarry Smith 
2253985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2254985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2255985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2256e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2257985db425SBarry Smith   for (i=0; i<m; i++) {
22589189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2259985db425SBarry Smith     for (j=1; j<n; j++) {
2260985db425SBarry Smith       atmp = PetscAbsScalar(aa[i+m*j]);
2261985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2262985db425SBarry Smith     }
2263985db425SBarry Smith   }
2264985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2265985db425SBarry Smith   PetscFunctionReturn(0);
2266985db425SBarry Smith }
2267985db425SBarry Smith 
2268e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2269985db425SBarry Smith {
2270985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2271985db425SBarry Smith   PetscErrorCode ierr;
2272d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
2273985db425SBarry Smith   PetscScalar    *x;
2274985db425SBarry Smith   MatScalar      *aa = a->v;
2275985db425SBarry Smith 
2276985db425SBarry Smith   PetscFunctionBegin;
2277e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2278985db425SBarry Smith 
2279985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2280985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2281985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2282e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2283985db425SBarry Smith   for (i=0; i<m; i++) {
2284985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2285985db425SBarry Smith     for (j=1; j<n; j++) {
2286985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
2287985db425SBarry Smith     }
2288985db425SBarry Smith   }
2289985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2290985db425SBarry Smith   PetscFunctionReturn(0);
2291985db425SBarry Smith }
2292985db425SBarry Smith 
2293e0877f53SBarry Smith static PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
22948d0534beSBarry Smith {
22958d0534beSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
22968d0534beSBarry Smith   PetscErrorCode ierr;
22978d0534beSBarry Smith   PetscScalar    *x;
22988d0534beSBarry Smith 
22998d0534beSBarry Smith   PetscFunctionBegin;
2300e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
23018d0534beSBarry Smith 
23028d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2303d0f46423SBarry Smith   ierr = PetscMemcpy(x,a->v+col*a->lda,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
23048d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
23058d0534beSBarry Smith   PetscFunctionReturn(0);
23068d0534beSBarry Smith }
23078d0534beSBarry Smith 
23080716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
23090716a85fSBarry Smith {
23100716a85fSBarry Smith   PetscErrorCode ierr;
23110716a85fSBarry Smith   PetscInt       i,j,m,n;
23120716a85fSBarry Smith   PetscScalar    *a;
23130716a85fSBarry Smith 
23140716a85fSBarry Smith   PetscFunctionBegin;
23150716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
23160716a85fSBarry Smith   ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr);
23178c778c55SBarry Smith   ierr = MatDenseGetArray(A,&a);CHKERRQ(ierr);
23180716a85fSBarry Smith   if (type == NORM_2) {
23190716a85fSBarry Smith     for (i=0; i<n; i++) {
23200716a85fSBarry Smith       for (j=0; j<m; j++) {
23210716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
23220716a85fSBarry Smith       }
23230716a85fSBarry Smith       a += m;
23240716a85fSBarry Smith     }
23250716a85fSBarry Smith   } else if (type == NORM_1) {
23260716a85fSBarry Smith     for (i=0; i<n; i++) {
23270716a85fSBarry Smith       for (j=0; j<m; j++) {
23280716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
23290716a85fSBarry Smith       }
23300716a85fSBarry Smith       a += m;
23310716a85fSBarry Smith     }
23320716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
23330716a85fSBarry Smith     for (i=0; i<n; i++) {
23340716a85fSBarry Smith       for (j=0; j<m; j++) {
23350716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
23360716a85fSBarry Smith       }
23370716a85fSBarry Smith       a += m;
23380716a85fSBarry Smith     }
2339ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
23408c778c55SBarry Smith   ierr = MatDenseRestoreArray(A,&a);CHKERRQ(ierr);
23410716a85fSBarry Smith   if (type == NORM_2) {
23428f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
23430716a85fSBarry Smith   }
23440716a85fSBarry Smith   PetscFunctionReturn(0);
23450716a85fSBarry Smith }
23460716a85fSBarry Smith 
234773a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
234873a71a0fSBarry Smith {
234973a71a0fSBarry Smith   PetscErrorCode ierr;
235073a71a0fSBarry Smith   PetscScalar    *a;
235173a71a0fSBarry Smith   PetscInt       m,n,i;
235273a71a0fSBarry Smith 
235373a71a0fSBarry Smith   PetscFunctionBegin;
235473a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
23558c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
235673a71a0fSBarry Smith   for (i=0; i<m*n; i++) {
235773a71a0fSBarry Smith     ierr = PetscRandomGetValue(rctx,a+i);CHKERRQ(ierr);
235873a71a0fSBarry Smith   }
23598c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
236073a71a0fSBarry Smith   PetscFunctionReturn(0);
236173a71a0fSBarry Smith }
236273a71a0fSBarry Smith 
23633b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
23643b49f96aSBarry Smith {
23653b49f96aSBarry Smith   PetscFunctionBegin;
23663b49f96aSBarry Smith   *missing = PETSC_FALSE;
23673b49f96aSBarry Smith   PetscFunctionReturn(0);
23683b49f96aSBarry Smith }
236973a71a0fSBarry Smith 
2370af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
237186aefd0dSHong Zhang {
237286aefd0dSHong Zhang   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
237386aefd0dSHong Zhang 
237486aefd0dSHong Zhang   PetscFunctionBegin;
237586aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
237686aefd0dSHong Zhang   *vals = a->v+col*a->lda;
237786aefd0dSHong Zhang   PetscFunctionReturn(0);
237886aefd0dSHong Zhang }
237986aefd0dSHong Zhang 
2380af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
238186aefd0dSHong Zhang {
238286aefd0dSHong Zhang   PetscFunctionBegin;
238386aefd0dSHong Zhang   *vals = 0; /* user cannot accidently use the array later */
238486aefd0dSHong Zhang   PetscFunctionReturn(0);
238586aefd0dSHong Zhang }
2386abc3b08eSStefano Zampini 
2387289bc588SBarry Smith /* -------------------------------------------------------------------*/
2388a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2389905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2390905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2391905e6a2fSBarry Smith                                         MatMult_SeqDense,
239297304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
23937c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
23947c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2395db4efbfdSBarry Smith                                         0,
2396db4efbfdSBarry Smith                                         0,
2397db4efbfdSBarry Smith                                         0,
2398db4efbfdSBarry Smith                                 /* 10*/ 0,
2399905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2400905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
240141f059aeSBarry Smith                                         MatSOR_SeqDense,
2402ec8511deSBarry Smith                                         MatTranspose_SeqDense,
240397304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2404905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2405905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2406905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2407905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2408c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2409c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2410905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2411905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2412d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2413db4efbfdSBarry Smith                                         0,
2414db4efbfdSBarry Smith                                         0,
2415db4efbfdSBarry Smith                                         0,
2416db4efbfdSBarry Smith                                         0,
24174994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2418273d9f13SBarry Smith                                         0,
2419905e6a2fSBarry Smith                                         0,
242073a71a0fSBarry Smith                                         0,
242173a71a0fSBarry Smith                                         0,
2422d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2423a5ae1ecdSBarry Smith                                         0,
2424a5ae1ecdSBarry Smith                                         0,
2425a5ae1ecdSBarry Smith                                         0,
2426a5ae1ecdSBarry Smith                                         0,
2427d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
24287dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2429a5ae1ecdSBarry Smith                                         0,
24304b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2431a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2432d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2433a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
24347d68702bSBarry Smith                                         MatShift_Basic,
2435a5ae1ecdSBarry Smith                                         0,
24363f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
243773a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2438a5ae1ecdSBarry Smith                                         0,
2439a5ae1ecdSBarry Smith                                         0,
2440a5ae1ecdSBarry Smith                                         0,
2441a5ae1ecdSBarry Smith                                         0,
2442d519adbfSMatthew Knepley                                 /* 54*/ 0,
2443a5ae1ecdSBarry Smith                                         0,
2444a5ae1ecdSBarry Smith                                         0,
2445a5ae1ecdSBarry Smith                                         0,
2446a5ae1ecdSBarry Smith                                         0,
2447d519adbfSMatthew Knepley                                 /* 59*/ 0,
2448e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2449e03a110bSBarry Smith                                         MatView_SeqDense,
2450357abbc8SBarry Smith                                         0,
245197304618SKris Buschelman                                         0,
2452d519adbfSMatthew Knepley                                 /* 64*/ 0,
245397304618SKris Buschelman                                         0,
245497304618SKris Buschelman                                         0,
245597304618SKris Buschelman                                         0,
245697304618SKris Buschelman                                         0,
2457d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
245897304618SKris Buschelman                                         0,
245997304618SKris Buschelman                                         0,
246097304618SKris Buschelman                                         0,
246197304618SKris Buschelman                                         0,
2462d519adbfSMatthew Knepley                                 /* 74*/ 0,
246397304618SKris Buschelman                                         0,
246497304618SKris Buschelman                                         0,
246597304618SKris Buschelman                                         0,
246697304618SKris Buschelman                                         0,
2467d519adbfSMatthew Knepley                                 /* 79*/ 0,
246897304618SKris Buschelman                                         0,
246997304618SKris Buschelman                                         0,
247097304618SKris Buschelman                                         0,
24715bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2472865e5f61SKris Buschelman                                         0,
24731cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2474865e5f61SKris Buschelman                                         0,
2475865e5f61SKris Buschelman                                         0,
2476865e5f61SKris Buschelman                                         0,
2477d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqDense_SeqDense,
2478a9fe9ddaSSatish Balay                                         MatMatMultSymbolic_SeqDense_SeqDense,
2479a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2480abc3b08eSStefano Zampini                                         MatPtAP_SeqDense_SeqDense,
2481abc3b08eSStefano Zampini                                         MatPtAPSymbolic_SeqDense_SeqDense,
2482abc3b08eSStefano Zampini                                 /* 94*/ MatPtAPNumeric_SeqDense_SeqDense,
248369f65d41SStefano Zampini                                         MatMatTransposeMult_SeqDense_SeqDense,
248469f65d41SStefano Zampini                                         MatMatTransposeMultSymbolic_SeqDense_SeqDense,
248569f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2486284134d9SBarry Smith                                         0,
2487d519adbfSMatthew Knepley                                 /* 99*/ 0,
2488284134d9SBarry Smith                                         0,
2489284134d9SBarry Smith                                         0,
2490ba337c44SJed Brown                                         MatConjugate_SeqDense,
2491f73d5cc4SBarry Smith                                         0,
2492ba337c44SJed Brown                                 /*104*/ 0,
2493ba337c44SJed Brown                                         MatRealPart_SeqDense,
2494ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2495985db425SBarry Smith                                         0,
2496985db425SBarry Smith                                         0,
24978208b9aeSStefano Zampini                                 /*109*/ 0,
2498985db425SBarry Smith                                         0,
24998d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2500aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
25013b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2502aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2503aabbc4fbSShri Abhyankar                                         0,
2504aabbc4fbSShri Abhyankar                                         0,
2505aabbc4fbSShri Abhyankar                                         0,
2506aabbc4fbSShri Abhyankar                                         0,
2507aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2508aabbc4fbSShri Abhyankar                                         0,
2509aabbc4fbSShri Abhyankar                                         0,
25100716a85fSBarry Smith                                         0,
25110716a85fSBarry Smith                                         0,
25120716a85fSBarry Smith                                 /*124*/ 0,
25135df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
25145df89d91SHong Zhang                                         0,
25155df89d91SHong Zhang                                         0,
25165df89d91SHong Zhang                                         0,
25175df89d91SHong Zhang                                 /*129*/ 0,
251875648e8dSHong Zhang                                         MatTransposeMatMult_SeqDense_SeqDense,
251975648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqDense_SeqDense,
252075648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
25213964eb88SJed Brown                                         0,
25223964eb88SJed Brown                                 /*134*/ 0,
25233964eb88SJed Brown                                         0,
25243964eb88SJed Brown                                         0,
25253964eb88SJed Brown                                         0,
25263964eb88SJed Brown                                         0,
25273964eb88SJed Brown                                 /*139*/ 0,
2528f9426fe0SMark Adams                                         0,
2529d528f656SJakub Kruzik                                         0,
2530d528f656SJakub Kruzik                                         0,
2531d528f656SJakub Kruzik                                         0,
2532d528f656SJakub Kruzik                                 /*144*/ MatCreateMPIMatConcatenateSeqMat_SeqDense
2533985db425SBarry Smith };
253490ace30eSBarry Smith 
25354b828684SBarry Smith /*@C
2536fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2537d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2538d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2539289bc588SBarry Smith 
2540db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
2541db81eaa0SLois Curfman McInnes 
254220563c6bSBarry Smith    Input Parameters:
2543db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
25440c775827SLois Curfman McInnes .  m - number of rows
254518f449edSLois Curfman McInnes .  n - number of columns
25460298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2547dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
254820563c6bSBarry Smith 
254920563c6bSBarry Smith    Output Parameter:
255044cd7ae7SLois Curfman McInnes .  A - the matrix
255120563c6bSBarry Smith 
2552b259b22eSLois Curfman McInnes    Notes:
255318f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
255418f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
25550298fd71SBarry Smith    set data=NULL.
255618f449edSLois Curfman McInnes 
2557027ccd11SLois Curfman McInnes    Level: intermediate
2558027ccd11SLois Curfman McInnes 
2559dbd7a890SLois Curfman McInnes .keywords: dense, matrix, LAPACK, BLAS
2560d65003e9SLois Curfman McInnes 
256169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
256220563c6bSBarry Smith @*/
25637087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2564289bc588SBarry Smith {
2565dfbe8321SBarry Smith   PetscErrorCode ierr;
25663b2fbd54SBarry Smith 
25673a40ed3dSBarry Smith   PetscFunctionBegin;
2568f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2569f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2570273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2571273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2572273d9f13SBarry Smith   PetscFunctionReturn(0);
2573273d9f13SBarry Smith }
2574273d9f13SBarry Smith 
2575273d9f13SBarry Smith /*@C
2576273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2577273d9f13SBarry Smith 
2578273d9f13SBarry Smith    Collective on MPI_Comm
2579273d9f13SBarry Smith 
2580273d9f13SBarry Smith    Input Parameters:
25811c4f3114SJed Brown +  B - the matrix
25820298fd71SBarry Smith -  data - the array (or NULL)
2583273d9f13SBarry Smith 
2584273d9f13SBarry Smith    Notes:
2585273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2586273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2587284134d9SBarry Smith    need not call this routine.
2588273d9f13SBarry Smith 
2589273d9f13SBarry Smith    Level: intermediate
2590273d9f13SBarry Smith 
2591273d9f13SBarry Smith .keywords: dense, matrix, LAPACK, BLAS
2592273d9f13SBarry Smith 
259369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA()
2594867c911aSBarry Smith 
2595273d9f13SBarry Smith @*/
25967087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2597273d9f13SBarry Smith {
25984ac538c5SBarry Smith   PetscErrorCode ierr;
2599a23d5eceSKris Buschelman 
2600a23d5eceSKris Buschelman   PetscFunctionBegin;
26014ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2602a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2603a23d5eceSKris Buschelman }
2604a23d5eceSKris Buschelman 
26057087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2606a23d5eceSKris Buschelman {
2607273d9f13SBarry Smith   Mat_SeqDense   *b;
2608dfbe8321SBarry Smith   PetscErrorCode ierr;
2609273d9f13SBarry Smith 
2610273d9f13SBarry Smith   PetscFunctionBegin;
2611273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2612a868139aSShri Abhyankar 
261334ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
261434ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
261534ef9618SShri Abhyankar 
2616273d9f13SBarry Smith   b       = (Mat_SeqDense*)B->data;
261786d161a7SShri Abhyankar   b->Mmax = B->rmap->n;
261886d161a7SShri Abhyankar   b->Nmax = B->cmap->n;
261986d161a7SShri Abhyankar   if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n;
262086d161a7SShri Abhyankar 
2621220afb94SBarry Smith   ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr);
26229e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
26239e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2624e92229d0SSatish Balay     ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr);
26253bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
26262205254eSKarl Rupp 
26279e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2628273d9f13SBarry Smith   } else { /* user-allocated storage */
26299e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2630273d9f13SBarry Smith     b->v          = data;
2631273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2632273d9f13SBarry Smith   }
26330450473dSBarry Smith   B->assembled = PETSC_TRUE;
2634273d9f13SBarry Smith   PetscFunctionReturn(0);
2635273d9f13SBarry Smith }
2636273d9f13SBarry Smith 
263765b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2638cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
26398baccfbdSHong Zhang {
2640d77f618aSHong Zhang   Mat            mat_elemental;
2641d77f618aSHong Zhang   PetscErrorCode ierr;
2642d77f618aSHong Zhang   PetscScalar    *array,*v_colwise;
2643d77f618aSHong Zhang   PetscInt       M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2644d77f618aSHong Zhang 
26458baccfbdSHong Zhang   PetscFunctionBegin;
2646d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
2647d77f618aSHong Zhang   ierr = MatDenseGetArray(A,&array);CHKERRQ(ierr);
2648d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2649d77f618aSHong Zhang   k = 0;
2650d77f618aSHong Zhang   for (j=0; j<N; j++) {
2651d77f618aSHong Zhang     cols[j] = j;
2652d77f618aSHong Zhang     for (i=0; i<M; i++) {
2653d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2654d77f618aSHong Zhang     }
2655d77f618aSHong Zhang   }
2656d77f618aSHong Zhang   for (i=0; i<M; i++) {
2657d77f618aSHong Zhang     rows[i] = i;
2658d77f618aSHong Zhang   }
2659d77f618aSHong Zhang   ierr = MatDenseRestoreArray(A,&array);CHKERRQ(ierr);
2660d77f618aSHong Zhang 
2661d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2662d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2663d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2664d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2665d77f618aSHong Zhang 
2666d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2667d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2668d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2669d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2670d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2671d77f618aSHong Zhang 
2672511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
267328be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2674d77f618aSHong Zhang   } else {
2675d77f618aSHong Zhang     *newmat = mat_elemental;
2676d77f618aSHong Zhang   }
26778baccfbdSHong Zhang   PetscFunctionReturn(0);
26788baccfbdSHong Zhang }
267965b80a83SHong Zhang #endif
26808baccfbdSHong Zhang 
26811b807ce4Svictorle /*@C
26821b807ce4Svictorle   MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array
26831b807ce4Svictorle 
26841b807ce4Svictorle   Input parameter:
26851b807ce4Svictorle + A - the matrix
26861b807ce4Svictorle - lda - the leading dimension
26871b807ce4Svictorle 
26881b807ce4Svictorle   Notes:
2689867c911aSBarry Smith   This routine is to be used in conjunction with MatSeqDenseSetPreallocation();
26901b807ce4Svictorle   it asserts that the preallocation has a leading dimension (the LDA parameter
26911b807ce4Svictorle   of Blas and Lapack fame) larger than M, the first dimension of the matrix.
26921b807ce4Svictorle 
26931b807ce4Svictorle   Level: intermediate
26941b807ce4Svictorle 
26951b807ce4Svictorle .keywords: dense, matrix, LAPACK, BLAS
26961b807ce4Svictorle 
2697284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize()
2698867c911aSBarry Smith 
26991b807ce4Svictorle @*/
27007087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetLDA(Mat B,PetscInt lda)
27011b807ce4Svictorle {
27021b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
270321a2c019SBarry Smith 
27041b807ce4Svictorle   PetscFunctionBegin;
2705e32f2f54SBarry 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);
27061b807ce4Svictorle   b->lda       = lda;
270721a2c019SBarry Smith   b->changelda = PETSC_FALSE;
270821a2c019SBarry Smith   b->Mmax      = PetscMax(b->Mmax,lda);
27091b807ce4Svictorle   PetscFunctionReturn(0);
27101b807ce4Svictorle }
27111b807ce4Svictorle 
2712d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
2713d528f656SJakub Kruzik {
2714d528f656SJakub Kruzik   PetscErrorCode ierr;
2715d528f656SJakub Kruzik   PetscMPIInt    size;
2716d528f656SJakub Kruzik 
2717d528f656SJakub Kruzik   PetscFunctionBegin;
2718d528f656SJakub Kruzik   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2719d528f656SJakub Kruzik   if (size == 1) {
2720d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
2721d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
2722d528f656SJakub Kruzik     } else {
2723d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2724d528f656SJakub Kruzik     }
2725d528f656SJakub Kruzik   } else {
2726d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
2727d528f656SJakub Kruzik   }
2728d528f656SJakub Kruzik   PetscFunctionReturn(0);
2729d528f656SJakub Kruzik }
2730d528f656SJakub Kruzik 
27310bad9183SKris Buschelman /*MC
2732fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
27330bad9183SKris Buschelman 
27340bad9183SKris Buschelman    Options Database Keys:
27350bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
27360bad9183SKris Buschelman 
27370bad9183SKris Buschelman   Level: beginner
27380bad9183SKris Buschelman 
273989665df3SBarry Smith .seealso: MatCreateSeqDense()
274089665df3SBarry Smith 
27410bad9183SKris Buschelman M*/
27420bad9183SKris Buschelman 
27438cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqDense(Mat B)
2744273d9f13SBarry Smith {
2745273d9f13SBarry Smith   Mat_SeqDense   *b;
2746dfbe8321SBarry Smith   PetscErrorCode ierr;
27477c334f02SBarry Smith   PetscMPIInt    size;
2748273d9f13SBarry Smith 
2749273d9f13SBarry Smith   PetscFunctionBegin;
2750ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
2751e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
275255659b69SBarry Smith 
2753b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
2754549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
275544cd7ae7SLois Curfman McInnes   B->data = (void*)b;
275618f449edSLois Curfman McInnes 
2757273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
27584e220ebcSLois Curfman McInnes 
2759*49a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
2760bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
27618572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2762d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
2763d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
27648572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2765715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2766bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
27678baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
27688baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
27698baccfbdSHong Zhang #endif
2770bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
2771bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaij_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2772bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2773bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2774abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaij_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
27754099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijperm_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
27764099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijperm_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
27774099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijperm_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
27784099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijperm_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
2779e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijsell_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2780e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijsell_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2781e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijsell_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2782e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijsell_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
278396e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijmkl_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
278496e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijmkl_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
278596e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijmkl_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
278696e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijmkl_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
278796e6d5c4SRichard Tran Mills 
27883bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaij_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
27893bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
27903bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
27914099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijperm_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
27924099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
27934099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2794e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijsell_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2795e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2796e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
279796e6d5c4SRichard Tran Mills 
279896e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijmkl_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
279996e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
280096e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2801af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
2802af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
280317667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
28043a40ed3dSBarry Smith   PetscFunctionReturn(0);
2805289bc588SBarry Smith }
280686aefd0dSHong Zhang 
280786aefd0dSHong Zhang /*@C
2808af53bab2SHong 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.
280986aefd0dSHong Zhang 
281086aefd0dSHong Zhang    Not Collective
281186aefd0dSHong Zhang 
281286aefd0dSHong Zhang    Input Parameter:
281386aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
281486aefd0dSHong Zhang -  col - column index
281586aefd0dSHong Zhang 
281686aefd0dSHong Zhang    Output Parameter:
281786aefd0dSHong Zhang .  vals - pointer to the data
281886aefd0dSHong Zhang 
281986aefd0dSHong Zhang    Level: intermediate
282086aefd0dSHong Zhang 
282186aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
282286aefd0dSHong Zhang @*/
282386aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
282486aefd0dSHong Zhang {
282586aefd0dSHong Zhang   PetscErrorCode ierr;
282686aefd0dSHong Zhang 
282786aefd0dSHong Zhang   PetscFunctionBegin;
282886aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
282986aefd0dSHong Zhang   PetscFunctionReturn(0);
283086aefd0dSHong Zhang }
283186aefd0dSHong Zhang 
283286aefd0dSHong Zhang /*@C
283386aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
283486aefd0dSHong Zhang 
283586aefd0dSHong Zhang    Not Collective
283686aefd0dSHong Zhang 
283786aefd0dSHong Zhang    Input Parameter:
283886aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
283986aefd0dSHong Zhang 
284086aefd0dSHong Zhang    Output Parameter:
284186aefd0dSHong Zhang .  vals - pointer to the data
284286aefd0dSHong Zhang 
284386aefd0dSHong Zhang    Level: intermediate
284486aefd0dSHong Zhang 
284586aefd0dSHong Zhang .seealso: MatDenseGetColumn()
284686aefd0dSHong Zhang @*/
284786aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
284886aefd0dSHong Zhang {
284986aefd0dSHong Zhang   PetscErrorCode ierr;
285086aefd0dSHong Zhang 
285186aefd0dSHong Zhang   PetscFunctionBegin;
285286aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
285386aefd0dSHong Zhang   PetscFunctionReturn(0);
285486aefd0dSHong Zhang }
2855