xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 8491ab44fbec860432103a865a3e7996b28f507a)
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 
11ca15aa20SStefano Zampini 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;
15ca15aa20SStefano Zampini   PetscScalar    *v;
16ca15aa20SStefano Zampini   PetscErrorCode ierr;
178c178816SStefano Zampini 
188c178816SStefano Zampini   PetscFunctionBegin;
198c178816SStefano Zampini   if (A->rmap->n != A->cmap->n) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot symmetrize a rectangular matrix");
20ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
218c178816SStefano Zampini   if (!hermitian) {
228c178816SStefano Zampini     for (k=0;k<n;k++) {
238c178816SStefano Zampini       for (j=k;j<n;j++) {
24ca15aa20SStefano Zampini         v[j*mat->lda + k] = v[k*mat->lda + j];
258c178816SStefano Zampini       }
268c178816SStefano Zampini     }
278c178816SStefano Zampini   } else {
288c178816SStefano Zampini     for (k=0;k<n;k++) {
298c178816SStefano Zampini       for (j=k;j<n;j++) {
30ca15aa20SStefano Zampini         v[j*mat->lda + k] = PetscConj(v[k*mat->lda + j]);
318c178816SStefano Zampini       }
328c178816SStefano Zampini     }
338c178816SStefano Zampini   }
34ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
358c178816SStefano Zampini   PetscFunctionReturn(0);
368c178816SStefano Zampini }
378c178816SStefano Zampini 
3805709791SSatish Balay PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A)
398c178816SStefano Zampini {
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);
57ca15aa20SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
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);
82ca15aa20SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
838c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
848c178816SStefano Zampini 
858c178816SStefano Zampini   A->ops->solve             = NULL;
868c178816SStefano Zampini   A->ops->matsolve          = NULL;
878c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
888c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
898c178816SStefano Zampini   A->ops->solveadd          = NULL;
908c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
918c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
928c178816SStefano Zampini   ierr                      = PetscFree(A->solvertype);CHKERRQ(ierr);
938c178816SStefano Zampini   PetscFunctionReturn(0);
948c178816SStefano Zampini }
958c178816SStefano Zampini 
963f49a652SStefano Zampini PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
973f49a652SStefano Zampini {
983f49a652SStefano Zampini   PetscErrorCode    ierr;
993f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1003f49a652SStefano Zampini   PetscInt          m  = l->lda, n = A->cmap->n,r = A->rmap->n, i,j;
101ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
1023f49a652SStefano Zampini   const PetscScalar *xx;
1033f49a652SStefano Zampini 
1043f49a652SStefano Zampini   PetscFunctionBegin;
1053f49a652SStefano Zampini #if defined(PETSC_USE_DEBUG)
1063f49a652SStefano Zampini   for (i=0; i<N; i++) {
1073f49a652SStefano Zampini     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1083f49a652SStefano 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);
1093f49a652SStefano 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);
1103f49a652SStefano Zampini   }
1113f49a652SStefano Zampini #endif
112ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
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 
131ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1323f49a652SStefano Zampini   for (i=0; i<N; i++) {
133ca15aa20SStefano Zampini     slot = v + rows[i]*m;
134580bdb30SBarry Smith     ierr = PetscArrayzero(slot,r);CHKERRQ(ierr);
1353f49a652SStefano Zampini   }
1363f49a652SStefano Zampini   for (i=0; i<N; i++) {
137ca15aa20SStefano Zampini     slot = v + rows[i];
1383f49a652SStefano Zampini     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
1393f49a652SStefano Zampini   }
1403f49a652SStefano Zampini   if (diag != 0.0) {
1413f49a652SStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1423f49a652SStefano Zampini     for (i=0; i<N; i++) {
143ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1443f49a652SStefano Zampini       *slot = diag;
1453f49a652SStefano Zampini     }
1463f49a652SStefano Zampini   }
147ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
1483f49a652SStefano Zampini   PetscFunctionReturn(0);
1493f49a652SStefano Zampini }
1503f49a652SStefano Zampini 
151abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C)
152abc3b08eSStefano Zampini {
153abc3b08eSStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)(C->data);
154abc3b08eSStefano Zampini   PetscErrorCode ierr;
155abc3b08eSStefano Zampini 
156abc3b08eSStefano Zampini   PetscFunctionBegin;
157ca15aa20SStefano Zampini   if (c->ptapwork) {
158ca15aa20SStefano Zampini     ierr = (*C->ops->matmultnumeric)(A,P,c->ptapwork);CHKERRQ(ierr);
159ca15aa20SStefano Zampini     ierr = (*C->ops->transposematmultnumeric)(P,c->ptapwork,C);CHKERRQ(ierr);
160ca15aa20SStefano Zampini   } else { /* first time went trough the basic. Should we add better dispatching for subclasses? */
161ca15aa20SStefano Zampini     ierr = MatPtAP_Basic(A,P,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
162ca15aa20SStefano Zampini   }
163abc3b08eSStefano Zampini   PetscFunctionReturn(0);
164abc3b08eSStefano Zampini }
165abc3b08eSStefano Zampini 
166abc3b08eSStefano Zampini PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat *C)
167abc3b08eSStefano Zampini {
168abc3b08eSStefano Zampini   Mat_SeqDense   *c;
169ca15aa20SStefano Zampini   PetscBool      flg;
170abc3b08eSStefano Zampini   PetscErrorCode ierr;
171abc3b08eSStefano Zampini 
172abc3b08eSStefano Zampini   PetscFunctionBegin;
173ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)P,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
174ca15aa20SStefano Zampini   ierr = MatCreate(PetscObjectComm((PetscObject)A),C);CHKERRQ(ierr);
175ca15aa20SStefano Zampini   ierr = MatSetSizes(*C,P->cmap->n,P->cmap->n,P->cmap->N,P->cmap->N);CHKERRQ(ierr);
176ca15aa20SStefano Zampini   ierr = MatSetType(*C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
177ca15aa20SStefano Zampini   ierr = MatSeqDenseSetPreallocation(*C,NULL);CHKERRQ(ierr);
178abc3b08eSStefano Zampini   c    = (Mat_SeqDense*)((*C)->data);
179ca15aa20SStefano Zampini   ierr = MatCreate(PetscObjectComm((PetscObject)A),&c->ptapwork);CHKERRQ(ierr);
180ca15aa20SStefano Zampini   ierr = MatSetSizes(c->ptapwork,A->rmap->n,P->cmap->n,A->rmap->N,P->cmap->N);CHKERRQ(ierr);
181ca15aa20SStefano Zampini   ierr = MatSetType(c->ptapwork,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
182ca15aa20SStefano Zampini   ierr = MatSeqDenseSetPreallocation(c->ptapwork,NULL);CHKERRQ(ierr);
183abc3b08eSStefano Zampini   PetscFunctionReturn(0);
184abc3b08eSStefano Zampini }
185abc3b08eSStefano Zampini 
186150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatPtAP_SeqDense_SeqDense(Mat A,Mat P,MatReuse reuse,PetscReal fill,Mat *C)
187abc3b08eSStefano Zampini {
188abc3b08eSStefano Zampini   PetscErrorCode ierr;
189abc3b08eSStefano Zampini 
190abc3b08eSStefano Zampini   PetscFunctionBegin;
191abc3b08eSStefano Zampini   if (reuse == MAT_INITIAL_MATRIX) {
192abc3b08eSStefano Zampini     ierr = MatPtAPSymbolic_SeqDense_SeqDense(A,P,fill,C);CHKERRQ(ierr);
193abc3b08eSStefano Zampini   }
194abc3b08eSStefano Zampini   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
195abc3b08eSStefano Zampini   ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
196abc3b08eSStefano Zampini   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
197abc3b08eSStefano Zampini   PetscFunctionReturn(0);
198abc3b08eSStefano Zampini }
199abc3b08eSStefano Zampini 
200cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
201b49cda9fSStefano Zampini {
202a13144ffSStefano Zampini   Mat            B = NULL;
203b49cda9fSStefano Zampini   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
204b49cda9fSStefano Zampini   Mat_SeqDense   *b;
205b49cda9fSStefano Zampini   PetscErrorCode ierr;
206b49cda9fSStefano Zampini   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i;
207b49cda9fSStefano Zampini   MatScalar      *av=a->a;
208a13144ffSStefano Zampini   PetscBool      isseqdense;
209b49cda9fSStefano Zampini 
210b49cda9fSStefano Zampini   PetscFunctionBegin;
211a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
212a13144ffSStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense);CHKERRQ(ierr);
213a32993e3SJed Brown     if (!isseqdense) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type_name);
214a13144ffSStefano Zampini   }
215a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
216b49cda9fSStefano Zampini     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
217b49cda9fSStefano Zampini     ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
218b49cda9fSStefano Zampini     ierr = MatSetType(B,MATSEQDENSE);CHKERRQ(ierr);
219b49cda9fSStefano Zampini     ierr = MatSeqDenseSetPreallocation(B,NULL);CHKERRQ(ierr);
220b49cda9fSStefano Zampini     b    = (Mat_SeqDense*)(B->data);
221a13144ffSStefano Zampini   } else {
222a13144ffSStefano Zampini     b    = (Mat_SeqDense*)((*newmat)->data);
223580bdb30SBarry Smith     ierr = PetscArrayzero(b->v,m*n);CHKERRQ(ierr);
224a13144ffSStefano Zampini   }
225b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
226b49cda9fSStefano Zampini     PetscInt j;
227b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
228b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
229b49cda9fSStefano Zampini       aj++;
230b49cda9fSStefano Zampini       av++;
231b49cda9fSStefano Zampini     }
232b49cda9fSStefano Zampini     ai++;
233b49cda9fSStefano Zampini   }
234b49cda9fSStefano Zampini 
235511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
236a13144ffSStefano Zampini     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
237a13144ffSStefano Zampini     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
23828be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
239b49cda9fSStefano Zampini   } else {
240a13144ffSStefano Zampini     if (B) *newmat = B;
241a13144ffSStefano Zampini     ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
242a13144ffSStefano Zampini     ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
243b49cda9fSStefano Zampini   }
244b49cda9fSStefano Zampini   PetscFunctionReturn(0);
245b49cda9fSStefano Zampini }
246b49cda9fSStefano Zampini 
247cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
2486a63e612SBarry Smith {
2496a63e612SBarry Smith   Mat            B;
2506a63e612SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2516a63e612SBarry Smith   PetscErrorCode ierr;
2529399e1b8SMatthew G. Knepley   PetscInt       i, j;
2539399e1b8SMatthew G. Knepley   PetscInt       *rows, *nnz;
2549399e1b8SMatthew G. Knepley   MatScalar      *aa = a->v, *vals;
2556a63e612SBarry Smith 
2566a63e612SBarry Smith   PetscFunctionBegin;
257ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
2586a63e612SBarry Smith   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
2596a63e612SBarry Smith   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
2609399e1b8SMatthew G. Knepley   ierr = PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals);CHKERRQ(ierr);
2619399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2629399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) ++nnz[i];
2636a63e612SBarry Smith     aa += a->lda;
2646a63e612SBarry Smith   }
2659399e1b8SMatthew G. Knepley   ierr = MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz);CHKERRQ(ierr);
2669399e1b8SMatthew G. Knepley   aa = a->v;
2679399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2689399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2699399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) {rows[numRows] = i; vals[numRows++] = aa[i];}
2709399e1b8SMatthew G. Knepley     ierr = MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr);
2719399e1b8SMatthew G. Knepley     aa  += a->lda;
2729399e1b8SMatthew G. Knepley   }
2739399e1b8SMatthew G. Knepley   ierr = PetscFree3(rows,nnz,vals);CHKERRQ(ierr);
2746a63e612SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2756a63e612SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2766a63e612SBarry Smith 
277511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
27828be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
2796a63e612SBarry Smith   } else {
2806a63e612SBarry Smith     *newmat = B;
2816a63e612SBarry Smith   }
2826a63e612SBarry Smith   PetscFunctionReturn(0);
2836a63e612SBarry Smith }
2846a63e612SBarry Smith 
285ca15aa20SStefano Zampini PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
2861987afe7SBarry Smith {
2871987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
288ca15aa20SStefano Zampini   const PetscScalar *xv;
289ca15aa20SStefano Zampini   PetscScalar       *yv;
2900805154bSBarry Smith   PetscBLASInt      N,m,ldax,lday,one = 1;
291efee365bSSatish Balay   PetscErrorCode    ierr;
2923a40ed3dSBarry Smith 
2933a40ed3dSBarry Smith   PetscFunctionBegin;
294ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(X,&xv);CHKERRQ(ierr);
295ca15aa20SStefano Zampini   ierr = MatDenseGetArray(Y,&yv);CHKERRQ(ierr);
296c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n*X->cmap->n,&N);CHKERRQ(ierr);
297c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n,&m);CHKERRQ(ierr);
298c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->lda,&ldax);CHKERRQ(ierr);
299c5df96a5SBarry Smith   ierr = PetscBLASIntCast(y->lda,&lday);CHKERRQ(ierr);
300a5ce6ee0Svictorle   if (ldax>m || lday>m) {
301ca15aa20SStefano Zampini     PetscInt j;
302ca15aa20SStefano Zampini 
303d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
304ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&alpha,xv+j*ldax,&one,yv+j*lday,&one));
305a5ce6ee0Svictorle     }
306a5ce6ee0Svictorle   } else {
307ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&alpha,xv,&one,yv,&one));
308a5ce6ee0Svictorle   }
309ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(X,&xv);CHKERRQ(ierr);
310ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(Y,&yv);CHKERRQ(ierr);
3110450473dSBarry Smith   ierr = PetscLogFlops(PetscMax(2*N-1,0));CHKERRQ(ierr);
3123a40ed3dSBarry Smith   PetscFunctionReturn(0);
3131987afe7SBarry Smith }
3141987afe7SBarry Smith 
315e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
316289bc588SBarry Smith {
317ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n*A->cmap->n;
3183a40ed3dSBarry Smith 
3193a40ed3dSBarry Smith   PetscFunctionBegin;
3204e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
321ca15aa20SStefano Zampini   info->nz_allocated      = N;
322ca15aa20SStefano Zampini   info->nz_used           = N;
323ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
324ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
3254e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3267adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3274e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3284e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3294e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3303a40ed3dSBarry Smith   PetscFunctionReturn(0);
331289bc588SBarry Smith }
332289bc588SBarry Smith 
333e0877f53SBarry Smith static PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
33480cd9d93SLois Curfman McInnes {
335273d9f13SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
336ca15aa20SStefano Zampini   PetscScalar    *v;
337efee365bSSatish Balay   PetscErrorCode ierr;
338c5df96a5SBarry Smith   PetscBLASInt   one = 1,j,nz,lda;
33980cd9d93SLois Curfman McInnes 
3403a40ed3dSBarry Smith   PetscFunctionBegin;
341ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
342c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->lda,&lda);CHKERRQ(ierr);
343d0f46423SBarry Smith   if (lda>A->rmap->n) {
344c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n,&nz);CHKERRQ(ierr);
345d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
346ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v+j*lda,&one));
347a5ce6ee0Svictorle     }
348a5ce6ee0Svictorle   } else {
349c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz);CHKERRQ(ierr);
350ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v,&one));
351a5ce6ee0Svictorle   }
352efee365bSSatish Balay   ierr = PetscLogFlops(nz);CHKERRQ(ierr);
353ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
3543a40ed3dSBarry Smith   PetscFunctionReturn(0);
35580cd9d93SLois Curfman McInnes }
35680cd9d93SLois Curfman McInnes 
357e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3581cbb95d3SBarry Smith {
3591cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
360ca15aa20SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
361ca15aa20SStefano Zampini   const PetscScalar *v;
362ca15aa20SStefano Zampini   PetscErrorCode    ierr;
3631cbb95d3SBarry Smith 
3641cbb95d3SBarry Smith   PetscFunctionBegin;
3651cbb95d3SBarry Smith   *fl = PETSC_FALSE;
366d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
367ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
3681cbb95d3SBarry Smith   for (i=0; i<m; i++) {
369ca15aa20SStefano Zampini     for (j=i; j<m; j++) {
3701cbb95d3SBarry Smith       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) PetscFunctionReturn(0);
3711cbb95d3SBarry Smith     }
3721cbb95d3SBarry Smith   }
373ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
3741cbb95d3SBarry Smith   *fl  = PETSC_TRUE;
3751cbb95d3SBarry Smith   PetscFunctionReturn(0);
3761cbb95d3SBarry Smith }
3771cbb95d3SBarry Smith 
378ca15aa20SStefano Zampini PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
379b24902e0SBarry Smith {
380ca15aa20SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
381b24902e0SBarry Smith   PetscErrorCode ierr;
382b24902e0SBarry Smith   PetscInt       lda = (PetscInt)mat->lda,j,m;
383b24902e0SBarry Smith 
384b24902e0SBarry Smith   PetscFunctionBegin;
385aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr);
386aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr);
3870298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr);
388b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
389ca15aa20SStefano Zampini     const PetscScalar *av;
390ca15aa20SStefano Zampini     PetscScalar       *v;
391ca15aa20SStefano Zampini 
392ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
393ca15aa20SStefano Zampini     ierr = MatDenseGetArray(newi,&v);CHKERRQ(ierr);
394d0f46423SBarry Smith     if (lda>A->rmap->n) {
395d0f46423SBarry Smith       m = A->rmap->n;
396d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
397ca15aa20SStefano Zampini         ierr = PetscArraycpy(v+j*m,av+j*lda,m);CHKERRQ(ierr);
398b24902e0SBarry Smith       }
399b24902e0SBarry Smith     } else {
400ca15aa20SStefano Zampini       ierr = PetscArraycpy(v,av,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
401b24902e0SBarry Smith     }
402ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(newi,&v);CHKERRQ(ierr);
403ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
404b24902e0SBarry Smith   }
405b24902e0SBarry Smith   PetscFunctionReturn(0);
406b24902e0SBarry Smith }
407b24902e0SBarry Smith 
408ca15aa20SStefano Zampini PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
40902cad45dSBarry Smith {
4106849ba73SBarry Smith   PetscErrorCode ierr;
41102cad45dSBarry Smith 
4123a40ed3dSBarry Smith   PetscFunctionBegin;
413ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr);
414d0f46423SBarry Smith   ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4155c9eb25fSBarry Smith   ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
416719d5645SBarry Smith   ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr);
417b24902e0SBarry Smith   PetscFunctionReturn(0);
418b24902e0SBarry Smith }
419b24902e0SBarry Smith 
420e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
421289bc588SBarry Smith {
4224482741eSBarry Smith   MatFactorInfo  info;
423a093e273SMatthew Knepley   PetscErrorCode ierr;
4243a40ed3dSBarry Smith 
4253a40ed3dSBarry Smith   PetscFunctionBegin;
426c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
427ca15aa20SStefano Zampini   ierr = (*fact->ops->lufactor)(fact,0,0,&info);CHKERRQ(ierr);
4283a40ed3dSBarry Smith   PetscFunctionReturn(0);
429289bc588SBarry Smith }
4306ee01492SSatish Balay 
431e0877f53SBarry Smith static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy)
432289bc588SBarry Smith {
433c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
4346849ba73SBarry Smith   PetscErrorCode    ierr;
435f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
436f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
437c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
43867e560aaSBarry Smith 
4393a40ed3dSBarry Smith   PetscFunctionBegin;
440c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
441f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4421ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
443580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
444d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_LU) {
44500121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4468b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
44700121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
448e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
449d5f3da31SBarry Smith   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
450a49dc2a2SStefano Zampini     if (A->spd) {
45100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4528b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
45300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
454e32f2f54SBarry Smith       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
455a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
456a49dc2a2SStefano Zampini     } else if (A->hermitian) {
45700121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
458a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
45900121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
460a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
461a49dc2a2SStefano Zampini #endif
462a49dc2a2SStefano Zampini     } else { /* symmetric case */
46300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
464a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
46500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
466a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
467a49dc2a2SStefano Zampini     }
4682205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
469f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4701ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
471dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
4723a40ed3dSBarry Smith   PetscFunctionReturn(0);
473289bc588SBarry Smith }
4746ee01492SSatish Balay 
475e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X)
47685e2c93fSHong Zhang {
47785e2c93fSHong Zhang   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
47885e2c93fSHong Zhang   PetscErrorCode    ierr;
4791683a169SBarry Smith   const PetscScalar *b;
4801683a169SBarry Smith   PetscScalar       *x;
481efb80c78SLisandro Dalcin   PetscInt          n;
482783b601eSJed Brown   PetscBLASInt      nrhs,info,m;
48385e2c93fSHong Zhang 
48485e2c93fSHong Zhang   PetscFunctionBegin;
485c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
4860298fd71SBarry Smith   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
487c5df96a5SBarry Smith   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
4881683a169SBarry Smith   ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
4898c778c55SBarry Smith   ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr);
49085e2c93fSHong Zhang 
491580bdb30SBarry Smith   ierr = PetscArraycpy(x,b,m*nrhs);CHKERRQ(ierr);
49285e2c93fSHong Zhang 
49385e2c93fSHong Zhang   if (A->factortype == MAT_FACTOR_LU) {
49400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4958b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
49600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
49785e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
49885e2c93fSHong Zhang   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
499a49dc2a2SStefano Zampini     if (A->spd) {
50000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5018b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
50200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
50385e2c93fSHong Zhang       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
504a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
505a49dc2a2SStefano Zampini     } else if (A->hermitian) {
50600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
507a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
50800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
509a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
510a49dc2a2SStefano Zampini #endif
511a49dc2a2SStefano Zampini     } else { /* symmetric case */
51200121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
513a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
51400121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
515a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
516a49dc2a2SStefano Zampini     }
5172205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
51885e2c93fSHong Zhang 
5191683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
5208c778c55SBarry Smith   ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr);
52185e2c93fSHong Zhang   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
52285e2c93fSHong Zhang   PetscFunctionReturn(0);
52385e2c93fSHong Zhang }
52485e2c93fSHong Zhang 
52500121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
52600121966SStefano Zampini 
527e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
528da3a660dSBarry Smith {
529c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
530dfbe8321SBarry Smith   PetscErrorCode    ierr;
531f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
532f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
533c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
53467e560aaSBarry Smith 
5353a40ed3dSBarry Smith   PetscFunctionBegin;
536c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
537f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5381ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
539580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
5408208b9aeSStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
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");
5458208b9aeSStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
546a49dc2a2SStefano Zampini     if (A->spd) {
54700121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
54800121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
54900121966SStefano Zampini #endif
55000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5518b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
55200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
55300121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
55400121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
55500121966SStefano Zampini #endif
556a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
557a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
558a49dc2a2SStefano Zampini     } else if (A->hermitian) {
55900121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
56000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
56100121966SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
56200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
56300121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
564ae7cfcebSSatish Balay #endif
565a49dc2a2SStefano Zampini     } else { /* symmetric case */
56600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
567a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
56800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
569a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
570da3a660dSBarry Smith     }
571a49dc2a2SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
572f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5731ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
574dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
5753a40ed3dSBarry Smith   PetscFunctionReturn(0);
576da3a660dSBarry Smith }
5776ee01492SSatish Balay 
578db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
579db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
580db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
581ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
582db4efbfdSBarry Smith {
583db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
584db4efbfdSBarry Smith   PetscErrorCode ierr;
585db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
586db4efbfdSBarry Smith 
587db4efbfdSBarry Smith   PetscFunctionBegin;
588c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
589c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
590db4efbfdSBarry Smith   if (!mat->pivots) {
5918208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
5923bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
593db4efbfdSBarry Smith   }
594db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
5958e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5968b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
5978e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
5988e57ea43SSatish Balay 
599e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
600e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
6018208b9aeSStefano Zampini 
602db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6038208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
604db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
605d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
606db4efbfdSBarry Smith 
607f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
608f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
609f6224b95SHong Zhang 
610dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
611db4efbfdSBarry Smith   PetscFunctionReturn(0);
612db4efbfdSBarry Smith }
613db4efbfdSBarry Smith 
614a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
615ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
616db4efbfdSBarry Smith {
617db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
618db4efbfdSBarry Smith   PetscErrorCode ierr;
619c5df96a5SBarry Smith   PetscBLASInt   info,n;
620db4efbfdSBarry Smith 
621db4efbfdSBarry Smith   PetscFunctionBegin;
622c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
623db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
624a49dc2a2SStefano Zampini   if (A->spd) {
62500121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6268b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
62700121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
628a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
629a49dc2a2SStefano Zampini   } else if (A->hermitian) {
630a49dc2a2SStefano Zampini     if (!mat->pivots) {
631a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
632a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
633a49dc2a2SStefano Zampini     }
634a49dc2a2SStefano Zampini     if (!mat->fwork) {
635a49dc2a2SStefano Zampini       PetscScalar dummy;
636a49dc2a2SStefano Zampini 
637a49dc2a2SStefano Zampini       mat->lfwork = -1;
63800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
639a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
64000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
641a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
642a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
643a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
644a49dc2a2SStefano Zampini     }
64500121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
646a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
64700121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
648a49dc2a2SStefano Zampini #endif
649a49dc2a2SStefano Zampini   } else { /* symmetric case */
650a49dc2a2SStefano Zampini     if (!mat->pivots) {
651a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
652a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
653a49dc2a2SStefano Zampini     }
654a49dc2a2SStefano Zampini     if (!mat->fwork) {
655a49dc2a2SStefano Zampini       PetscScalar dummy;
656a49dc2a2SStefano Zampini 
657a49dc2a2SStefano Zampini       mat->lfwork = -1;
65800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
659a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
66000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
661a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
662a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
663a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
664a49dc2a2SStefano Zampini     }
66500121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
666a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
66700121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
668a49dc2a2SStefano Zampini   }
669e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
6708208b9aeSStefano Zampini 
671db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6728208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
673db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
674d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
6752205254eSKarl Rupp 
676f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
677f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
678f6224b95SHong Zhang 
679eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
680db4efbfdSBarry Smith   PetscFunctionReturn(0);
681db4efbfdSBarry Smith }
682db4efbfdSBarry Smith 
683db4efbfdSBarry Smith 
6840481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
685db4efbfdSBarry Smith {
686db4efbfdSBarry Smith   PetscErrorCode ierr;
687db4efbfdSBarry Smith   MatFactorInfo  info;
688db4efbfdSBarry Smith 
689db4efbfdSBarry Smith   PetscFunctionBegin;
690db4efbfdSBarry Smith   info.fill = 1.0;
6912205254eSKarl Rupp 
692c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
693ca15aa20SStefano Zampini   ierr = (*fact->ops->choleskyfactor)(fact,0,&info);CHKERRQ(ierr);
694db4efbfdSBarry Smith   PetscFunctionReturn(0);
695db4efbfdSBarry Smith }
696db4efbfdSBarry Smith 
697ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
698db4efbfdSBarry Smith {
699db4efbfdSBarry Smith   PetscFunctionBegin;
700c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
7011bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
702719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
703bd443b22SStefano Zampini   fact->ops->solve                 = MatSolve_SeqDense;
704bd443b22SStefano Zampini   fact->ops->matsolve              = MatMatSolve_SeqDense;
705bd443b22SStefano Zampini   fact->ops->solvetranspose        = MatSolveTranspose_SeqDense;
706db4efbfdSBarry Smith   PetscFunctionReturn(0);
707db4efbfdSBarry Smith }
708db4efbfdSBarry Smith 
709ca15aa20SStefano Zampini PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
710db4efbfdSBarry Smith {
711db4efbfdSBarry Smith   PetscFunctionBegin;
712b66fe19dSMatthew G Knepley   fact->preallocated           = PETSC_TRUE;
713c3ef05f6SHong Zhang   fact->assembled              = PETSC_TRUE;
714719d5645SBarry Smith   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
715bd443b22SStefano Zampini   fact->ops->solve             = MatSolve_SeqDense;
716bd443b22SStefano Zampini   fact->ops->matsolve          = MatMatSolve_SeqDense;
717bd443b22SStefano Zampini   fact->ops->solvetranspose    = MatSolveTranspose_SeqDense;
718db4efbfdSBarry Smith   PetscFunctionReturn(0);
719db4efbfdSBarry Smith }
720db4efbfdSBarry Smith 
721ca15aa20SStefano Zampini /* uses LAPACK */
722cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
723db4efbfdSBarry Smith {
724db4efbfdSBarry Smith   PetscErrorCode ierr;
725db4efbfdSBarry Smith 
726db4efbfdSBarry Smith   PetscFunctionBegin;
727ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
728db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
729ca15aa20SStefano Zampini   ierr = MatSetType(*fact,MATDENSE);CHKERRQ(ierr);
730db4efbfdSBarry Smith   if (ftype == MAT_FACTOR_LU) {
731db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
732db4efbfdSBarry Smith   } else {
733db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
734db4efbfdSBarry Smith   }
735d5f3da31SBarry Smith   (*fact)->factortype = ftype;
73600c67f3bSHong Zhang 
73700c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
73800c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
739db4efbfdSBarry Smith   PetscFunctionReturn(0);
740db4efbfdSBarry Smith }
741db4efbfdSBarry Smith 
742289bc588SBarry Smith /* ------------------------------------------------------------------*/
743e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
744289bc588SBarry Smith {
745c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
746d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
747d9ca1df4SBarry Smith   const PetscScalar *b;
748dfbe8321SBarry Smith   PetscErrorCode    ierr;
749d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
750c5df96a5SBarry Smith   PetscBLASInt      o = 1,bm;
751289bc588SBarry Smith 
7523a40ed3dSBarry Smith   PetscFunctionBegin;
753ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
754c70f7ee4SJunchao Zhang   if (A->offloadmask == PETSC_OFFLOAD_GPU) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
755ca15aa20SStefano Zampini #endif
756422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
757c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
758289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
7593bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
7602dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
761289bc588SBarry Smith   }
7621ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
763d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
764b965ef7fSBarry Smith   its  = its*lits;
765e32f2f54SBarry 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);
766289bc588SBarry Smith   while (its--) {
767fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
768289bc588SBarry Smith       for (i=0; i<m; i++) {
7693bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
77055a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
771289bc588SBarry Smith       }
772289bc588SBarry Smith     }
773fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
774289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
7753bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
77655a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
777289bc588SBarry Smith       }
778289bc588SBarry Smith     }
779289bc588SBarry Smith   }
780d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
7811ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
7823a40ed3dSBarry Smith   PetscFunctionReturn(0);
783289bc588SBarry Smith }
784289bc588SBarry Smith 
785289bc588SBarry Smith /* -----------------------------------------------------------------*/
786ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
787289bc588SBarry Smith {
788c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
789d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
790d9ca1df4SBarry Smith   PetscScalar       *y;
791dfbe8321SBarry Smith   PetscErrorCode    ierr;
7920805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
793ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
7943a40ed3dSBarry Smith 
7953a40ed3dSBarry Smith   PetscFunctionBegin;
796c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
797c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
798d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
7992bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
8005ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8015ac36cfcSBarry Smith     PetscBLASInt i;
8025ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
8035ac36cfcSBarry Smith   } else {
8048b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
8055ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
8065ac36cfcSBarry Smith   }
807d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8082bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
8093a40ed3dSBarry Smith   PetscFunctionReturn(0);
810289bc588SBarry Smith }
811800995b7SMatthew Knepley 
812ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
813289bc588SBarry Smith {
814c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
815d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
816dfbe8321SBarry Smith   PetscErrorCode    ierr;
8170805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
818d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
8193a40ed3dSBarry Smith 
8203a40ed3dSBarry Smith   PetscFunctionBegin;
821c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
822c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
823d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8242bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
8255ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8265ac36cfcSBarry Smith     PetscBLASInt i;
8275ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
8285ac36cfcSBarry Smith   } else {
8298b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
8305ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
8315ac36cfcSBarry Smith   }
832d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8332bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
8343a40ed3dSBarry Smith   PetscFunctionReturn(0);
835289bc588SBarry Smith }
8366ee01492SSatish Balay 
837ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
838289bc588SBarry Smith {
839c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
840d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
841d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
842dfbe8321SBarry Smith   PetscErrorCode    ierr;
8430805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
8443a40ed3dSBarry Smith 
8453a40ed3dSBarry Smith   PetscFunctionBegin;
846c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
847c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
848d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
849600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
850d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8511ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8528b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
853d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8541ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
855dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8563a40ed3dSBarry Smith   PetscFunctionReturn(0);
857289bc588SBarry Smith }
8586ee01492SSatish Balay 
859ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
860289bc588SBarry Smith {
861c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
862d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
863d9ca1df4SBarry Smith   PetscScalar       *y;
864dfbe8321SBarry Smith   PetscErrorCode    ierr;
8650805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
86687828ca2SBarry Smith   PetscScalar       _DOne=1.0;
8673a40ed3dSBarry Smith 
8683a40ed3dSBarry Smith   PetscFunctionBegin;
869c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
870c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
871d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
872600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
873d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8741ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8758b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
876d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8771ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
878dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8793a40ed3dSBarry Smith   PetscFunctionReturn(0);
880289bc588SBarry Smith }
881289bc588SBarry Smith 
882289bc588SBarry Smith /* -----------------------------------------------------------------*/
883e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
884289bc588SBarry Smith {
885c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
8866849ba73SBarry Smith   PetscErrorCode ierr;
88713f74950SBarry Smith   PetscInt       i;
88867e560aaSBarry Smith 
8893a40ed3dSBarry Smith   PetscFunctionBegin;
890d0f46423SBarry Smith   *ncols = A->cmap->n;
891289bc588SBarry Smith   if (cols) {
892854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
893d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
894289bc588SBarry Smith   }
895289bc588SBarry Smith   if (vals) {
896ca15aa20SStefano Zampini     const PetscScalar *v;
897ca15aa20SStefano Zampini 
898ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
899854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
900ca15aa20SStefano Zampini     v   += row;
901d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
902ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
903289bc588SBarry Smith   }
9043a40ed3dSBarry Smith   PetscFunctionReturn(0);
905289bc588SBarry Smith }
9066ee01492SSatish Balay 
907e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
908289bc588SBarry Smith {
909dfbe8321SBarry Smith   PetscErrorCode ierr;
9106e111a19SKarl Rupp 
911606d414cSSatish Balay   PetscFunctionBegin;
912606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
913606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
9143a40ed3dSBarry Smith   PetscFunctionReturn(0);
915289bc588SBarry Smith }
916289bc588SBarry Smith /* ----------------------------------------------------------------*/
917e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
918289bc588SBarry Smith {
919c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
920ca15aa20SStefano Zampini   PetscScalar      *av;
92113f74950SBarry Smith   PetscInt         i,j,idx=0;
922ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
923c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
924ca15aa20SStefano Zampini #endif
925ca15aa20SStefano Zampini   PetscErrorCode   ierr;
926d6dfbf8fSBarry Smith 
9273a40ed3dSBarry Smith   PetscFunctionBegin;
928ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&av);CHKERRQ(ierr);
929289bc588SBarry Smith   if (!mat->roworiented) {
930dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
931289bc588SBarry Smith       for (j=0; j<n; j++) {
932cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
9332515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
934e32f2f54SBarry Smith         if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
93558804f6dSBarry Smith #endif
936289bc588SBarry Smith         for (i=0; i<m; i++) {
937cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
9382515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
939e32f2f54SBarry Smith           if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
94058804f6dSBarry Smith #endif
941ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
942289bc588SBarry Smith         }
943289bc588SBarry Smith       }
9443a40ed3dSBarry Smith     } else {
945289bc588SBarry Smith       for (j=0; j<n; j++) {
946cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
9472515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
948e32f2f54SBarry Smith         if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
94958804f6dSBarry Smith #endif
950289bc588SBarry Smith         for (i=0; i<m; i++) {
951cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
9522515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
953e32f2f54SBarry Smith           if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
95458804f6dSBarry Smith #endif
955ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
956289bc588SBarry Smith         }
957289bc588SBarry Smith       }
958289bc588SBarry Smith     }
9593a40ed3dSBarry Smith   } else {
960dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
961e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
962cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
9632515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
964e32f2f54SBarry Smith         if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
96558804f6dSBarry Smith #endif
966e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
967cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
9682515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
969e32f2f54SBarry Smith           if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
97058804f6dSBarry Smith #endif
971ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
972e8d4e0b9SBarry Smith         }
973e8d4e0b9SBarry Smith       }
9743a40ed3dSBarry Smith     } else {
975289bc588SBarry Smith       for (i=0; i<m; i++) {
976cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
9772515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
978e32f2f54SBarry Smith         if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
97958804f6dSBarry Smith #endif
980289bc588SBarry Smith         for (j=0; j<n; j++) {
981cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
9822515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
983e32f2f54SBarry Smith           if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
98458804f6dSBarry Smith #endif
985ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
986289bc588SBarry Smith         }
987289bc588SBarry Smith       }
988289bc588SBarry Smith     }
989e8d4e0b9SBarry Smith   }
990ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
991ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
992c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
993c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
994ca15aa20SStefano Zampini #endif
995ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&av);CHKERRQ(ierr);
996ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
997c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
998ca15aa20SStefano Zampini #endif
9993a40ed3dSBarry Smith   PetscFunctionReturn(0);
1000289bc588SBarry Smith }
1001e8d4e0b9SBarry Smith 
1002e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1003ae80bb75SLois Curfman McInnes {
1004ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1005ca15aa20SStefano Zampini   const PetscScalar *vv;
100613f74950SBarry Smith   PetscInt          i,j;
1007ca15aa20SStefano Zampini   PetscErrorCode    ierr;
1008ae80bb75SLois Curfman McInnes 
10093a40ed3dSBarry Smith   PetscFunctionBegin;
1010ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1011ae80bb75SLois Curfman McInnes   /* row-oriented output */
1012ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
101397e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1014e32f2f54SBarry 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);
1015ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
10166f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1017e32f2f54SBarry 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);
1018ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1019ae80bb75SLois Curfman McInnes     }
1020ae80bb75SLois Curfman McInnes   }
1021ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
10223a40ed3dSBarry Smith   PetscFunctionReturn(0);
1023ae80bb75SLois Curfman McInnes }
1024ae80bb75SLois Curfman McInnes 
1025289bc588SBarry Smith /* -----------------------------------------------------------------*/
1026289bc588SBarry Smith 
1027*8491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1028aabbc4fbSShri Abhyankar {
1029aabbc4fbSShri Abhyankar   PetscErrorCode    ierr;
1030*8491ab44SLisandro Dalcin   PetscBool         skipHeader;
1031*8491ab44SLisandro Dalcin   PetscViewerFormat format;
1032*8491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
1033*8491ab44SLisandro Dalcin   const PetscScalar *v;
1034*8491ab44SLisandro Dalcin   PetscScalar       *vwork;
1035aabbc4fbSShri Abhyankar 
1036aabbc4fbSShri Abhyankar   PetscFunctionBegin;
1037*8491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1038*8491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
1039*8491ab44SLisandro Dalcin   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1040*8491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1041aabbc4fbSShri Abhyankar 
1042*8491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
1043*8491ab44SLisandro Dalcin 
1044*8491ab44SLisandro Dalcin   /* write matrix header */
1045*8491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
1046*8491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
1047*8491ab44SLisandro Dalcin   if (!skipHeader) {ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);}
1048*8491ab44SLisandro Dalcin 
1049*8491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
1050*8491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
1051*8491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
1052*8491ab44SLisandro Dalcin     /* store row lengths for each row */
1053*8491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
1054*8491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
1055*8491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
1056*8491ab44SLisandro Dalcin     /* store column indices (zero start index) */
1057*8491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
1058*8491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
1059*8491ab44SLisandro Dalcin         iwork[k] = j;
1060*8491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
1061*8491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
1062*8491ab44SLisandro Dalcin   }
1063*8491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
1064*8491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
1065*8491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
1066*8491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
1067*8491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
1068*8491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
1069*8491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
1070*8491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
1071*8491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
1072*8491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
1073*8491ab44SLisandro Dalcin   PetscFunctionReturn(0);
1074*8491ab44SLisandro Dalcin }
1075*8491ab44SLisandro Dalcin 
1076*8491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
1077*8491ab44SLisandro Dalcin {
1078*8491ab44SLisandro Dalcin   PetscErrorCode ierr;
1079*8491ab44SLisandro Dalcin   PetscBool      skipHeader;
1080*8491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
1081*8491ab44SLisandro Dalcin   PetscInt       rows,cols;
1082*8491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
1083*8491ab44SLisandro Dalcin 
1084*8491ab44SLisandro Dalcin   PetscFunctionBegin;
1085*8491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1086*8491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
1087*8491ab44SLisandro Dalcin 
1088*8491ab44SLisandro Dalcin   if (!skipHeader) {
1089*8491ab44SLisandro Dalcin     ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
1090*8491ab44SLisandro Dalcin     if (header[0] != MAT_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
1091*8491ab44SLisandro Dalcin     M = header[1]; N = header[2];
1092*8491ab44SLisandro Dalcin     if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M);
1093*8491ab44SLisandro Dalcin     if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N);
1094*8491ab44SLisandro Dalcin     nz = header[3];
1095*8491ab44SLisandro Dalcin     if (nz != MATRIX_BINARY_FORMAT_DENSE && nz < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %D in file",nz);
1096aabbc4fbSShri Abhyankar   } else {
1097*8491ab44SLisandro Dalcin     ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
1098*8491ab44SLisandro Dalcin     if (M < 0 || N < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Matrix binary file header was skipped, thus the user must specify the global sizes of input matrix");
1099*8491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1100e6324fbbSBarry Smith   }
1101aabbc4fbSShri Abhyankar 
1102*8491ab44SLisandro Dalcin   /* setup global sizes if not set */
1103*8491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
1104*8491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
1105*8491ab44SLisandro Dalcin   ierr = MatSetUp(mat);CHKERRQ(ierr);
1106*8491ab44SLisandro Dalcin   /* check if global sizes are correct */
1107*8491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
1108*8491ab44SLisandro Dalcin   if (M != rows || N != cols) SETERRQ4(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different sizes (%d, %d) than the input matrix (%d, %d)",M,N,rows,cols);
1109aabbc4fbSShri Abhyankar 
1110*8491ab44SLisandro Dalcin   ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
1111*8491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
1112*8491ab44SLisandro Dalcin   ierr = MatDenseGetArray(mat,&v);CHKERRQ(ierr);
1113*8491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
1114*8491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
1115*8491ab44SLisandro Dalcin     PetscInt nnz = m*N;
1116*8491ab44SLisandro Dalcin     /* read in matrix values */
1117*8491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&vwork);CHKERRQ(ierr);
1118*8491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
1119*8491ab44SLisandro Dalcin     /* store values in column major order */
1120*8491ab44SLisandro Dalcin     for (j=0; j<N; j++)
1121*8491ab44SLisandro Dalcin       for (i=0; i<m; i++)
1122*8491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
1123*8491ab44SLisandro Dalcin     ierr = PetscFree(vwork);CHKERRQ(ierr);
1124*8491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
1125*8491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
1126*8491ab44SLisandro Dalcin     /* read in row lengths */
1127*8491ab44SLisandro Dalcin     ierr = PetscMalloc1(m,&rlens);CHKERRQ(ierr);
1128*8491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
1129*8491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
1130*8491ab44SLisandro Dalcin     /* read in column indices and values */
1131*8491ab44SLisandro Dalcin     ierr = PetscMalloc2(nnz,&icols,nnz,&vwork);CHKERRQ(ierr);
1132*8491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
1133*8491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
1134*8491ab44SLisandro Dalcin     /* store values in column major order */
1135*8491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
1136*8491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
1137*8491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
1138*8491ab44SLisandro Dalcin     ierr = PetscFree(rlens);CHKERRQ(ierr);
1139*8491ab44SLisandro Dalcin     ierr = PetscFree2(icols,vwork);CHKERRQ(ierr);
1140aabbc4fbSShri Abhyankar   }
1141*8491ab44SLisandro Dalcin   ierr = MatDenseRestoreArray(mat,&v);CHKERRQ(ierr);
1142*8491ab44SLisandro Dalcin   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1143*8491ab44SLisandro Dalcin   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1144aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1145aabbc4fbSShri Abhyankar }
1146aabbc4fbSShri Abhyankar 
1147eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1148eb91f321SVaclav Hapla {
1149eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1150eb91f321SVaclav Hapla   PetscErrorCode ierr;
1151eb91f321SVaclav Hapla 
1152eb91f321SVaclav Hapla   PetscFunctionBegin;
1153eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1154eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1155eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
1156eb91f321SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1157eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1158eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1159eb91f321SVaclav Hapla   if (isbinary) {
1160*8491ab44SLisandro Dalcin     ierr = MatLoad_Dense_Binary(newMat,viewer);CHKERRQ(ierr);
1161eb91f321SVaclav Hapla   } else if (ishdf5) {
1162eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
1163eb91f321SVaclav Hapla     ierr = MatLoad_Dense_HDF5(newMat,viewer);CHKERRQ(ierr);
1164eb91f321SVaclav Hapla #else
1165eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1166eb91f321SVaclav Hapla #endif
1167eb91f321SVaclav Hapla   } else {
1168eb91f321SVaclav Hapla     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);
1169eb91f321SVaclav Hapla   }
1170eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1171eb91f321SVaclav Hapla }
1172eb91f321SVaclav Hapla 
11736849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1174289bc588SBarry Smith {
1175932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1176dfbe8321SBarry Smith   PetscErrorCode    ierr;
117713f74950SBarry Smith   PetscInt          i,j;
11782dcb1b2aSMatthew Knepley   const char        *name;
1179ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1180f3ef73ceSBarry Smith   PetscViewerFormat format;
11815f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1182ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
11835f481a85SSatish Balay #endif
1184932b0c3eSLois Curfman McInnes 
11853a40ed3dSBarry Smith   PetscFunctionBegin;
1186ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1187b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1188456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
11893a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1190fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1191d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1192d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1193ca15aa20SStefano Zampini       v    = av + i;
119477431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1195d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1196aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1197329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
119857622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1199329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
120057622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
12016831982aSBarry Smith         }
120280cd9d93SLois Curfman McInnes #else
12036831982aSBarry Smith         if (*v) {
120457622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
12056831982aSBarry Smith         }
120680cd9d93SLois Curfman McInnes #endif
12071b807ce4Svictorle         v += a->lda;
120880cd9d93SLois Curfman McInnes       }
1209b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
121080cd9d93SLois Curfman McInnes     }
1211d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
12123a40ed3dSBarry Smith   } else {
1213d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1214aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
121547989497SBarry Smith     /* determine if matrix has all real values */
1216ca15aa20SStefano Zampini     v = av;
1217d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1218ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
121947989497SBarry Smith     }
122047989497SBarry Smith #endif
1221fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
12223a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1223d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1224d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1225fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1226ffac6cdbSBarry Smith     }
1227ffac6cdbSBarry Smith 
1228d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1229ca15aa20SStefano Zampini       v = av + i;
1230d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1231aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
123247989497SBarry Smith         if (allreal) {
1233c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
123447989497SBarry Smith         } else {
1235c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
123647989497SBarry Smith         }
1237289bc588SBarry Smith #else
1238c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1239289bc588SBarry Smith #endif
12401b807ce4Svictorle         v += a->lda;
1241289bc588SBarry Smith       }
1242b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1243289bc588SBarry Smith     }
1244fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1245b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1246ffac6cdbSBarry Smith     }
1247d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1248da3a660dSBarry Smith   }
1249ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1250b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
12513a40ed3dSBarry Smith   PetscFunctionReturn(0);
1252289bc588SBarry Smith }
1253289bc588SBarry Smith 
1254*8491ab44SLisandro Dalcin static PetscErrorCode MatView_SeqDense_Binary(Mat mat,PetscViewer viewer)
1255932b0c3eSLois Curfman McInnes {
12566849ba73SBarry Smith   PetscErrorCode    ierr;
1257f4403165SShri Abhyankar   PetscViewerFormat format;
1258*8491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
1259*8491ab44SLisandro Dalcin   const PetscScalar *v;
1260*8491ab44SLisandro Dalcin   PetscScalar       *vwork;
1261932b0c3eSLois Curfman McInnes 
12623a40ed3dSBarry Smith   PetscFunctionBegin;
1263*8491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1264*8491ab44SLisandro Dalcin 
1265f4403165SShri Abhyankar   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1266*8491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
12672205254eSKarl Rupp 
1268*8491ab44SLisandro Dalcin   /* write matrix header */
1269*8491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
1270*8491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
1271*8491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);
12722205254eSKarl Rupp 
1273*8491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
1274*8491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
1275*8491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
1276*8491ab44SLisandro Dalcin     /* store row lengths for each row */
1277*8491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
1278*8491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
1279*8491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWrite(viewer,iwork,m,PETSC_INT);CHKERRQ(ierr);
1280932b0c3eSLois Curfman McInnes     /* store column indices (zero start index) */
1281*8491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
1282*8491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
1283*8491ab44SLisandro Dalcin         iwork[k] = j;
1284*8491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWrite(viewer,iwork,nnz,PETSC_INT);CHKERRQ(ierr);
1285*8491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
1286932b0c3eSLois Curfman McInnes   }
1287*8491ab44SLisandro Dalcin   /* store the matrix values as a dense matrix in row major order */
1288*8491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
1289*8491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
1290*8491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
1291*8491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
1292*8491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
1293*8491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
1294*8491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
1295*8491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWrite(viewer,vwork,m*N,PETSC_SCALAR);CHKERRQ(ierr);
1296*8491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
12973a40ed3dSBarry Smith   PetscFunctionReturn(0);
1298932b0c3eSLois Curfman McInnes }
1299932b0c3eSLois Curfman McInnes 
13009804daf3SBarry Smith #include <petscdraw.h>
1301e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1302f1af5d2fSBarry Smith {
1303f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
13046849ba73SBarry Smith   PetscErrorCode    ierr;
1305383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1306383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1307ca15aa20SStefano Zampini   const PetscScalar *v;
1308b0a32e0cSBarry Smith   PetscViewer       viewer;
1309b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1310f3ef73ceSBarry Smith   PetscViewerFormat format;
1311f1af5d2fSBarry Smith 
1312f1af5d2fSBarry Smith   PetscFunctionBegin;
1313f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1314b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1315b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1316f1af5d2fSBarry Smith 
1317f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1318ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1319fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1320383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1321f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1322f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1323383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1324f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1325f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1326f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1327ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1328ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1329ca15aa20SStefano Zampini         else continue;
1330b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1331f1af5d2fSBarry Smith       }
1332f1af5d2fSBarry Smith     }
1333383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1334f1af5d2fSBarry Smith   } else {
1335f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1336f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1337b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1338b05fc000SLisandro Dalcin     PetscDraw popup;
1339b05fc000SLisandro Dalcin 
1340f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1341f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1342f1af5d2fSBarry Smith     }
1343383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1344b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
134545f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1346383922c3SLisandro Dalcin 
1347383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1348f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1349f1af5d2fSBarry Smith       x_l = j;
1350f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1351f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1352f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1353f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1354b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1355b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1356f1af5d2fSBarry Smith       }
1357f1af5d2fSBarry Smith     }
1358383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1359f1af5d2fSBarry Smith   }
1360ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1361f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1362f1af5d2fSBarry Smith }
1363f1af5d2fSBarry Smith 
1364e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1365f1af5d2fSBarry Smith {
1366b0a32e0cSBarry Smith   PetscDraw      draw;
1367ace3abfcSBarry Smith   PetscBool      isnull;
1368329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1369dfbe8321SBarry Smith   PetscErrorCode ierr;
1370f1af5d2fSBarry Smith 
1371f1af5d2fSBarry Smith   PetscFunctionBegin;
1372b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1373b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1374abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1375f1af5d2fSBarry Smith 
1376d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1377f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1378b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1379832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1380b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
13810298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1382832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1383f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1384f1af5d2fSBarry Smith }
1385f1af5d2fSBarry Smith 
1386dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1387932b0c3eSLois Curfman McInnes {
1388dfbe8321SBarry Smith   PetscErrorCode ierr;
1389ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1390932b0c3eSLois Curfman McInnes 
13913a40ed3dSBarry Smith   PetscFunctionBegin;
1392251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1393251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1394251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
13950f5bd95cSBarry Smith 
1396c45a1595SBarry Smith   if (iascii) {
1397c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
13980f5bd95cSBarry Smith   } else if (isbinary) {
13993a40ed3dSBarry Smith     ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr);
1400f1af5d2fSBarry Smith   } else if (isdraw) {
1401f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1402932b0c3eSLois Curfman McInnes   }
14033a40ed3dSBarry Smith   PetscFunctionReturn(0);
1404932b0c3eSLois Curfman McInnes }
1405289bc588SBarry Smith 
1406d3042a70SBarry Smith static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar array[])
1407d3042a70SBarry Smith {
1408d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1409d3042a70SBarry Smith 
1410d3042a70SBarry Smith   PetscFunctionBegin;
1411d3042a70SBarry Smith   a->unplacedarray       = a->v;
1412d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1413d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1414ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1415c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1416ca15aa20SStefano Zampini #endif
1417d3042a70SBarry Smith   PetscFunctionReturn(0);
1418d3042a70SBarry Smith }
1419d3042a70SBarry Smith 
1420d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1421d3042a70SBarry Smith {
1422d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1423d3042a70SBarry Smith 
1424d3042a70SBarry Smith   PetscFunctionBegin;
1425d3042a70SBarry Smith   a->v             = a->unplacedarray;
1426d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1427d3042a70SBarry Smith   a->unplacedarray = NULL;
1428ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1429c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1430ca15aa20SStefano Zampini #endif
1431d3042a70SBarry Smith   PetscFunctionReturn(0);
1432d3042a70SBarry Smith }
1433d3042a70SBarry Smith 
1434ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1435289bc588SBarry Smith {
1436ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1437dfbe8321SBarry Smith   PetscErrorCode ierr;
143890f02eecSBarry Smith 
14393a40ed3dSBarry Smith   PetscFunctionBegin;
1440aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1441d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1442a5a9c739SBarry Smith #endif
144305b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1444a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1445abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
14466857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1447bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1448dbd8c25aSHong Zhang 
1449dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
145049a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1451bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
145252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
1453d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1454d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
145552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL);CHKERRQ(ierr);
145652c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL);CHKERRQ(ierr);
14578baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
14588baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
14598baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
14608baccfbdSHong Zhang #endif
14612bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
14622bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL);CHKERRQ(ierr);
1463a4af7ca8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaijcusparse_seqdense_C",NULL);CHKERRQ(ierr);
1464a4af7ca8SStefano Zampini #endif
1465a4af7ca8SStefano Zampini #if defined(PETSC_HAVE_VIENNACL)
1466a4af7ca8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaijviennacl_seqdense_C",NULL);CHKERRQ(ierr);
14672bf066beSStefano Zampini #endif
1468bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
1469bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1470bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1471bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1472a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1473a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1474a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1475c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
1476c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
1477c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
1478abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatPtAP_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
147952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
148052c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
148152c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
148252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatPtAP_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
148352c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
148452c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
148552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
148652c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatPtAP_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
148752c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
148852c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
148952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
149052c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_nest_seqdense_C",NULL);CHKERRQ(ierr);
149152c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_nest_seqdense_C",NULL);CHKERRQ(ierr);
149252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_nest_seqdense_C",NULL);CHKERRQ(ierr);
149352c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatPtAP_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
149452c5f739Sprj- 
14953bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14963bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14973bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
149852c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMult_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
149952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
150052c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
150152c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMult_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
150252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
150352c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
150452c5f739Sprj- 
150552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMult_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
150652c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
150752c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
150886aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
150986aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
15103a40ed3dSBarry Smith   PetscFunctionReturn(0);
1511289bc588SBarry Smith }
1512289bc588SBarry Smith 
1513e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1514289bc588SBarry Smith {
1515c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
15166849ba73SBarry Smith   PetscErrorCode ierr;
151713f74950SBarry Smith   PetscInt       k,j,m,n,M;
151887828ca2SBarry Smith   PetscScalar    *v,tmp;
151948b35521SBarry Smith 
15203a40ed3dSBarry Smith   PetscFunctionBegin;
1521ca15aa20SStefano Zampini   m = A->rmap->n; M = mat->lda; n = A->cmap->n;
15222847e3fdSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX && m == n) { /* in place transpose */
1523ca15aa20SStefano Zampini     ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1524d3e5ee88SLois Curfman McInnes     for (j=0; j<m; j++) {
1525289bc588SBarry Smith       for (k=0; k<j; k++) {
15261b807ce4Svictorle         tmp        = v[j + k*M];
15271b807ce4Svictorle         v[j + k*M] = v[k + j*M];
15281b807ce4Svictorle         v[k + j*M] = tmp;
1529289bc588SBarry Smith       }
1530289bc588SBarry Smith     }
1531ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
15323a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1533d3e5ee88SLois Curfman McInnes     Mat          tmat;
1534ec8511deSBarry Smith     Mat_SeqDense *tmatd;
153587828ca2SBarry Smith     PetscScalar  *v2;
1536af36a384SStefano Zampini     PetscInt     M2;
1537ea709b57SSatish Balay 
15382847e3fdSStefano Zampini     if (reuse != MAT_REUSE_MATRIX) {
1539ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1540d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
15417adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
15420298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1543ca15aa20SStefano Zampini     } else tmat = *matout;
1544ca15aa20SStefano Zampini 
1545ca15aa20SStefano Zampini     ierr  = MatDenseGetArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
1546ca15aa20SStefano Zampini     ierr  = MatDenseGetArray(tmat,&v2);CHKERRQ(ierr);
1547ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1548ca15aa20SStefano Zampini     M2    = tmatd->lda;
1549d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1550af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1551d3e5ee88SLois Curfman McInnes     }
1552ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(tmat,&v2);CHKERRQ(ierr);
1553ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
15546d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15556d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15562847e3fdSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) *matout = tmat;
15572847e3fdSStefano Zampini     else {
15582847e3fdSStefano Zampini       ierr = MatHeaderMerge(A,&tmat);CHKERRQ(ierr);
15592847e3fdSStefano Zampini     }
156048b35521SBarry Smith   }
15613a40ed3dSBarry Smith   PetscFunctionReturn(0);
1562289bc588SBarry Smith }
1563289bc588SBarry Smith 
1564e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1565289bc588SBarry Smith {
1566c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1567c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1568ca15aa20SStefano Zampini   PetscInt          i;
1569ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
1570ca15aa20SStefano Zampini   PetscErrorCode    ierr;
15719ea5d5aeSSatish Balay 
15723a40ed3dSBarry Smith   PetscFunctionBegin;
1573d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1574d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1575ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A1,&v1);CHKERRQ(ierr);
1576ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A2,&v2);CHKERRQ(ierr);
1577ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
1578ca15aa20SStefano Zampini     ierr = PetscArraycmp(v1,v2,A1->rmap->n,flg);CHKERRQ(ierr);
1579ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1580ca15aa20SStefano Zampini     v1 += mat1->lda;
1581ca15aa20SStefano Zampini     v2 += mat2->lda;
15821b807ce4Svictorle   }
1583ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A1,&v1);CHKERRQ(ierr);
1584ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A2,&v2);CHKERRQ(ierr);
158577c4ece6SBarry Smith   *flg = PETSC_TRUE;
15863a40ed3dSBarry Smith   PetscFunctionReturn(0);
1587289bc588SBarry Smith }
1588289bc588SBarry Smith 
1589e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1590289bc588SBarry Smith {
1591c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
159213f74950SBarry Smith   PetscInt          i,n,len;
1593ca15aa20SStefano Zampini   PetscScalar       *x;
1594ca15aa20SStefano Zampini   const PetscScalar *vv;
1595ca15aa20SStefano Zampini   PetscErrorCode    ierr;
159644cd7ae7SLois Curfman McInnes 
15973a40ed3dSBarry Smith   PetscFunctionBegin;
15987a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
15991ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1600d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1601ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1602e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
160344cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1604ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1605289bc588SBarry Smith   }
1606ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
16071ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
16083a40ed3dSBarry Smith   PetscFunctionReturn(0);
1609289bc588SBarry Smith }
1610289bc588SBarry Smith 
1611e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1612289bc588SBarry Smith {
1613c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1614f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1615ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1616dfbe8321SBarry Smith   PetscErrorCode    ierr;
1617d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
161855659b69SBarry Smith 
16193a40ed3dSBarry Smith   PetscFunctionBegin;
1620ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&vv);CHKERRQ(ierr);
162128988994SBarry Smith   if (ll) {
16227a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1623f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1624e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1625da3a660dSBarry Smith     for (i=0; i<m; i++) {
1626da3a660dSBarry Smith       x = l[i];
1627ca15aa20SStefano Zampini       v = vv + i;
1628b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1629da3a660dSBarry Smith     }
1630f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1631eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1632da3a660dSBarry Smith   }
163328988994SBarry Smith   if (rr) {
16347a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1635f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1636e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1637da3a660dSBarry Smith     for (i=0; i<n; i++) {
1638da3a660dSBarry Smith       x = r[i];
1639ca15aa20SStefano Zampini       v = vv + i*mat->lda;
16402205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1641da3a660dSBarry Smith     }
1642f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1643eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1644da3a660dSBarry Smith   }
1645ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&vv);CHKERRQ(ierr);
16463a40ed3dSBarry Smith   PetscFunctionReturn(0);
1647289bc588SBarry Smith }
1648289bc588SBarry Smith 
1649ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1650289bc588SBarry Smith {
1651c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1652ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1653329f5518SBarry Smith   PetscReal         sum  = 0.0;
1654d0f46423SBarry Smith   PetscInt          lda  =mat->lda,m=A->rmap->n,i,j;
1655efee365bSSatish Balay   PetscErrorCode    ierr;
165655659b69SBarry Smith 
16573a40ed3dSBarry Smith   PetscFunctionBegin;
1658ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
1659ca15aa20SStefano Zampini   v    = vv;
1660289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1661a5ce6ee0Svictorle     if (lda>m) {
1662d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1663ca15aa20SStefano Zampini         v = vv+j*lda;
1664a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1665a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1666a5ce6ee0Svictorle         }
1667a5ce6ee0Svictorle       }
1668a5ce6ee0Svictorle     } else {
1669570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1670570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1671570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1672570b7f6dSBarry Smith     }
1673570b7f6dSBarry Smith #else
1674d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1675329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1676289bc588SBarry Smith       }
1677a5ce6ee0Svictorle     }
16788f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1679570b7f6dSBarry Smith #endif
1680dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16813a40ed3dSBarry Smith   } else if (type == NORM_1) {
1682064f8208SBarry Smith     *nrm = 0.0;
1683d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1684ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
1685289bc588SBarry Smith       sum = 0.0;
1686d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
168733a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1688289bc588SBarry Smith       }
1689064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1690289bc588SBarry Smith     }
1691eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16923a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1693064f8208SBarry Smith     *nrm = 0.0;
1694d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1695ca15aa20SStefano Zampini       v   = vv + j;
1696289bc588SBarry Smith       sum = 0.0;
1697d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
16981b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1699289bc588SBarry Smith       }
1700064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1701289bc588SBarry Smith     }
1702eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1703e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
1704ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
17053a40ed3dSBarry Smith   PetscFunctionReturn(0);
1706289bc588SBarry Smith }
1707289bc588SBarry Smith 
1708e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1709289bc588SBarry Smith {
1710c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
171163ba0a88SBarry Smith   PetscErrorCode ierr;
171267e560aaSBarry Smith 
17133a40ed3dSBarry Smith   PetscFunctionBegin;
1714b5a2b587SKris Buschelman   switch (op) {
1715b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
17164e0d8c25SBarry Smith     aij->roworiented = flg;
1717b5a2b587SKris Buschelman     break;
1718512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1719b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
17203971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
17214e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
172213fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1723b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1724b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
17250f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
17265021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
1727071fcb05SBarry Smith   case MAT_SORTED_FULL:
17285021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
17295021d80fSJed Brown     break;
17305021d80fSJed Brown   case MAT_SPD:
173177e54ba9SKris Buschelman   case MAT_SYMMETRIC:
173277e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
17339a4540c5SBarry Smith   case MAT_HERMITIAN:
17349a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
17355021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
173677e54ba9SKris Buschelman     break;
1737b5a2b587SKris Buschelman   default:
1738e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
17393a40ed3dSBarry Smith   }
17403a40ed3dSBarry Smith   PetscFunctionReturn(0);
1741289bc588SBarry Smith }
1742289bc588SBarry Smith 
1743e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
17446f0a148fSBarry Smith {
1745ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
17466849ba73SBarry Smith   PetscErrorCode ierr;
1747d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
1748ca15aa20SStefano Zampini   PetscScalar    *v;
17493a40ed3dSBarry Smith 
17503a40ed3dSBarry Smith   PetscFunctionBegin;
1751ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1752a5ce6ee0Svictorle   if (lda>m) {
1753d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1754ca15aa20SStefano Zampini       ierr = PetscArrayzero(v+j*lda,m);CHKERRQ(ierr);
1755a5ce6ee0Svictorle     }
1756a5ce6ee0Svictorle   } else {
1757ca15aa20SStefano Zampini     ierr = PetscArrayzero(v,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
1758a5ce6ee0Svictorle   }
1759ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17603a40ed3dSBarry Smith   PetscFunctionReturn(0);
17616f0a148fSBarry Smith }
17626f0a148fSBarry Smith 
1763e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
17646f0a148fSBarry Smith {
176597b48c8fSBarry Smith   PetscErrorCode    ierr;
1766ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1767b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
1768ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
176997b48c8fSBarry Smith   const PetscScalar *xx;
177055659b69SBarry Smith 
17713a40ed3dSBarry Smith   PetscFunctionBegin;
1772b9679d65SBarry Smith #if defined(PETSC_USE_DEBUG)
1773b9679d65SBarry Smith   for (i=0; i<N; i++) {
1774b9679d65SBarry Smith     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1775b9679d65SBarry 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);
1776b9679d65SBarry Smith   }
1777b9679d65SBarry Smith #endif
1778ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1779b9679d65SBarry Smith 
178097b48c8fSBarry Smith   /* fix right hand side if needed */
178197b48c8fSBarry Smith   if (x && b) {
178297b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
178397b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
17842205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
178597b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
178697b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
178797b48c8fSBarry Smith   }
178897b48c8fSBarry Smith 
1789ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
17906f0a148fSBarry Smith   for (i=0; i<N; i++) {
1791ca15aa20SStefano Zampini     slot = v + rows[i];
1792b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
17936f0a148fSBarry Smith   }
1794f4df32b1SMatthew Knepley   if (diag != 0.0) {
1795b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
17966f0a148fSBarry Smith     for (i=0; i<N; i++) {
1797ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1798f4df32b1SMatthew Knepley       *slot = diag;
17996f0a148fSBarry Smith     }
18006f0a148fSBarry Smith   }
1801ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
18023a40ed3dSBarry Smith   PetscFunctionReturn(0);
18036f0a148fSBarry Smith }
1804557bce09SLois Curfman McInnes 
180549a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
180649a6ff4bSBarry Smith {
180749a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
180849a6ff4bSBarry Smith 
180949a6ff4bSBarry Smith   PetscFunctionBegin;
181049a6ff4bSBarry Smith   *lda = mat->lda;
181149a6ff4bSBarry Smith   PetscFunctionReturn(0);
181249a6ff4bSBarry Smith }
181349a6ff4bSBarry Smith 
1814ca15aa20SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar *array[])
181564e87e97SBarry Smith {
1816c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
18173a40ed3dSBarry Smith 
18183a40ed3dSBarry Smith   PetscFunctionBegin;
181964e87e97SBarry Smith   *array = mat->v;
18203a40ed3dSBarry Smith   PetscFunctionReturn(0);
182164e87e97SBarry Smith }
18220754003eSLois Curfman McInnes 
1823ca15aa20SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar *array[])
1824ff14e315SSatish Balay {
18253a40ed3dSBarry Smith   PetscFunctionBegin;
18263a40ed3dSBarry Smith   PetscFunctionReturn(0);
1827ff14e315SSatish Balay }
18280754003eSLois Curfman McInnes 
1829dec5eb66SMatthew G Knepley /*@C
183049a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
183149a6ff4bSBarry Smith 
183249a6ff4bSBarry Smith    Logically Collective on Mat
183349a6ff4bSBarry Smith 
183449a6ff4bSBarry Smith    Input Parameter:
183549a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
183649a6ff4bSBarry Smith 
183749a6ff4bSBarry Smith    Output Parameter:
183849a6ff4bSBarry Smith .   lda - the leading dimension
183949a6ff4bSBarry Smith 
184049a6ff4bSBarry Smith    Level: intermediate
184149a6ff4bSBarry Smith 
184249a6ff4bSBarry Smith .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatSeqDenseSetLDA()
184349a6ff4bSBarry Smith @*/
184449a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
184549a6ff4bSBarry Smith {
184649a6ff4bSBarry Smith   PetscErrorCode ierr;
184749a6ff4bSBarry Smith 
184849a6ff4bSBarry Smith   PetscFunctionBegin;
184949a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
185049a6ff4bSBarry Smith   PetscFunctionReturn(0);
185149a6ff4bSBarry Smith }
185249a6ff4bSBarry Smith 
185349a6ff4bSBarry Smith /*@C
18548c778c55SBarry Smith    MatDenseGetArray - gives access to the array where the data for a SeqDense matrix is stored
185573a71a0fSBarry Smith 
18568572280aSBarry Smith    Logically Collective on Mat
185773a71a0fSBarry Smith 
185873a71a0fSBarry Smith    Input Parameter:
1859579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
186073a71a0fSBarry Smith 
186173a71a0fSBarry Smith    Output Parameter:
186273a71a0fSBarry Smith .   array - pointer to the data
186373a71a0fSBarry Smith 
186473a71a0fSBarry Smith    Level: intermediate
186573a71a0fSBarry Smith 
18668572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
186773a71a0fSBarry Smith @*/
18688c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
186973a71a0fSBarry Smith {
187073a71a0fSBarry Smith   PetscErrorCode ierr;
187173a71a0fSBarry Smith 
187273a71a0fSBarry Smith   PetscFunctionBegin;
18738c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
187473a71a0fSBarry Smith   PetscFunctionReturn(0);
187573a71a0fSBarry Smith }
187673a71a0fSBarry Smith 
1877dec5eb66SMatthew G Knepley /*@C
1878579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
187973a71a0fSBarry Smith 
18808572280aSBarry Smith    Logically Collective on Mat
18818572280aSBarry Smith 
18828572280aSBarry Smith    Input Parameters:
1883a2b725a8SWilliam Gropp +  mat - a MATSEQDENSE or MATMPIDENSE matrix
1884a2b725a8SWilliam Gropp -  array - pointer to the data
18858572280aSBarry Smith 
18868572280aSBarry Smith    Level: intermediate
18878572280aSBarry Smith 
18888572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
18898572280aSBarry Smith @*/
18908572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
18918572280aSBarry Smith {
18928572280aSBarry Smith   PetscErrorCode ierr;
18938572280aSBarry Smith 
18948572280aSBarry Smith   PetscFunctionBegin;
18958572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
18968572280aSBarry Smith   if (array) *array = NULL;
18978572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
18988572280aSBarry Smith   PetscFunctionReturn(0);
18998572280aSBarry Smith }
19008572280aSBarry Smith 
19018572280aSBarry Smith /*@C
19028572280aSBarry Smith    MatDenseGetArrayRead - gives access to the array where the data for a SeqDense matrix is stored
19038572280aSBarry Smith 
19048572280aSBarry Smith    Not Collective
19058572280aSBarry Smith 
19068572280aSBarry Smith    Input Parameter:
19078572280aSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
19088572280aSBarry Smith 
19098572280aSBarry Smith    Output Parameter:
19108572280aSBarry Smith .   array - pointer to the data
19118572280aSBarry Smith 
19128572280aSBarry Smith    Level: intermediate
19138572280aSBarry Smith 
19148572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArray(), MatDenseRestoreArrayRead()
19158572280aSBarry Smith @*/
19168572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
19178572280aSBarry Smith {
19188572280aSBarry Smith   PetscErrorCode ierr;
19198572280aSBarry Smith 
19208572280aSBarry Smith   PetscFunctionBegin;
19218572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
19228572280aSBarry Smith   PetscFunctionReturn(0);
19238572280aSBarry Smith }
19248572280aSBarry Smith 
19258572280aSBarry Smith /*@C
19268572280aSBarry Smith    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
19278572280aSBarry Smith 
192873a71a0fSBarry Smith    Not Collective
192973a71a0fSBarry Smith 
193073a71a0fSBarry Smith    Input Parameters:
1931a2b725a8SWilliam Gropp +  mat - a MATSEQDENSE or MATMPIDENSE matrix
1932a2b725a8SWilliam Gropp -  array - pointer to the data
193373a71a0fSBarry Smith 
193473a71a0fSBarry Smith    Level: intermediate
193573a71a0fSBarry Smith 
19368572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArray()
193773a71a0fSBarry Smith @*/
19388572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
193973a71a0fSBarry Smith {
194073a71a0fSBarry Smith   PetscErrorCode ierr;
194173a71a0fSBarry Smith 
194273a71a0fSBarry Smith   PetscFunctionBegin;
19438572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
19448572280aSBarry Smith   if (array) *array = NULL;
194573a71a0fSBarry Smith   PetscFunctionReturn(0);
194673a71a0fSBarry Smith }
194773a71a0fSBarry Smith 
19487dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
19490754003eSLois Curfman McInnes {
1950c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
19516849ba73SBarry Smith   PetscErrorCode ierr;
1952ca15aa20SStefano Zampini   PetscInt       i,j,nrows,ncols,blda;
19535d0c19d7SBarry Smith   const PetscInt *irow,*icol;
195487828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
19550754003eSLois Curfman McInnes   Mat            newmat;
19560754003eSLois Curfman McInnes 
19573a40ed3dSBarry Smith   PetscFunctionBegin;
195878b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
195978b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1960e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1961e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
19620754003eSLois Curfman McInnes 
1963182d2002SSatish Balay   /* Check submatrixcall */
1964182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
196513f74950SBarry Smith     PetscInt n_cols,n_rows;
1966182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
196721a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
1968f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
1969c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
197021a2c019SBarry Smith     }
1971182d2002SSatish Balay     newmat = *B;
1972182d2002SSatish Balay   } else {
19730754003eSLois Curfman McInnes     /* Create and fill new matrix */
1974ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
1975f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
19767adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
19770298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1978182d2002SSatish Balay   }
1979182d2002SSatish Balay 
1980182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1981ca15aa20SStefano Zampini   ierr = MatDenseGetArray(newmat,&bv);CHKERRQ(ierr);
1982ca15aa20SStefano Zampini   ierr = MatDenseGetLDA(newmat,&blda);CHKERRQ(ierr);
1983182d2002SSatish Balay   for (i=0; i<ncols; i++) {
19846de62eeeSBarry Smith     av = v + mat->lda*icol[i];
1985ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
1986ca15aa20SStefano Zampini     bv += blda;
19870754003eSLois Curfman McInnes   }
1988ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(newmat,&bv);CHKERRQ(ierr);
1989182d2002SSatish Balay 
1990182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
19916d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19926d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19930754003eSLois Curfman McInnes 
19940754003eSLois Curfman McInnes   /* Free work space */
199578b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
199678b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1997182d2002SSatish Balay   *B   = newmat;
19983a40ed3dSBarry Smith   PetscFunctionReturn(0);
19990754003eSLois Curfman McInnes }
20000754003eSLois Curfman McInnes 
20017dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2002905e6a2fSBarry Smith {
20036849ba73SBarry Smith   PetscErrorCode ierr;
200413f74950SBarry Smith   PetscInt       i;
2005905e6a2fSBarry Smith 
20063a40ed3dSBarry Smith   PetscFunctionBegin;
2007905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2008df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
2009905e6a2fSBarry Smith   }
2010905e6a2fSBarry Smith 
2011905e6a2fSBarry Smith   for (i=0; i<n; i++) {
20127dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2013905e6a2fSBarry Smith   }
20143a40ed3dSBarry Smith   PetscFunctionReturn(0);
2015905e6a2fSBarry Smith }
2016905e6a2fSBarry Smith 
2017e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2018c0aa2d19SHong Zhang {
2019c0aa2d19SHong Zhang   PetscFunctionBegin;
2020c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2021c0aa2d19SHong Zhang }
2022c0aa2d19SHong Zhang 
2023e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2024c0aa2d19SHong Zhang {
2025c0aa2d19SHong Zhang   PetscFunctionBegin;
2026c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2027c0aa2d19SHong Zhang }
2028c0aa2d19SHong Zhang 
2029e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
20304b0e389bSBarry Smith {
20314b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
20326849ba73SBarry Smith   PetscErrorCode    ierr;
2033ca15aa20SStefano Zampini   const PetscScalar *va;
2034ca15aa20SStefano Zampini   PetscScalar       *vb;
2035d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
20363a40ed3dSBarry Smith 
20373a40ed3dSBarry Smith   PetscFunctionBegin;
203833f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
203933f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
2040cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
20413a40ed3dSBarry Smith     PetscFunctionReturn(0);
20423a40ed3dSBarry Smith   }
2043e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
2044ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&va);CHKERRQ(ierr);
2045ca15aa20SStefano Zampini   ierr = MatDenseGetArray(B,&vb);CHKERRQ(ierr);
2046a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
20470dbb7854Svictorle     for (j=0; j<n; j++) {
2048ca15aa20SStefano Zampini       ierr = PetscArraycpy(vb+j*lda2,va+j*lda1,m);CHKERRQ(ierr);
2049a5ce6ee0Svictorle     }
2050a5ce6ee0Svictorle   } else {
2051ca15aa20SStefano Zampini     ierr = PetscArraycpy(vb,va,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2052a5ce6ee0Svictorle   }
2053ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(B,&vb);CHKERRQ(ierr);
2054ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&va);CHKERRQ(ierr);
2055ca15aa20SStefano Zampini   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2056ca15aa20SStefano Zampini   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2057273d9f13SBarry Smith   PetscFunctionReturn(0);
2058273d9f13SBarry Smith }
2059273d9f13SBarry Smith 
2060e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
2061273d9f13SBarry Smith {
2062dfbe8321SBarry Smith   PetscErrorCode ierr;
2063273d9f13SBarry Smith 
2064273d9f13SBarry Smith   PetscFunctionBegin;
2065273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
20663a40ed3dSBarry Smith   PetscFunctionReturn(0);
20674b0e389bSBarry Smith }
20684b0e389bSBarry Smith 
2069ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2070ba337c44SJed Brown {
2071ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2072ca15aa20SStefano Zampini   PetscScalar    *aa;
2073ca15aa20SStefano Zampini   PetscErrorCode ierr;
2074ba337c44SJed Brown 
2075ba337c44SJed Brown   PetscFunctionBegin;
2076ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2077ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2078ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2079ba337c44SJed Brown   PetscFunctionReturn(0);
2080ba337c44SJed Brown }
2081ba337c44SJed Brown 
2082ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2083ba337c44SJed Brown {
2084ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2085ca15aa20SStefano Zampini   PetscScalar    *aa;
2086ca15aa20SStefano Zampini   PetscErrorCode ierr;
2087ba337c44SJed Brown 
2088ba337c44SJed Brown   PetscFunctionBegin;
2089ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2090ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2091ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2092ba337c44SJed Brown   PetscFunctionReturn(0);
2093ba337c44SJed Brown }
2094ba337c44SJed Brown 
2095ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2096ba337c44SJed Brown {
2097ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2098ca15aa20SStefano Zampini   PetscScalar    *aa;
2099ca15aa20SStefano Zampini   PetscErrorCode ierr;
2100ba337c44SJed Brown 
2101ba337c44SJed Brown   PetscFunctionBegin;
2102ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2103ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
2104ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2105ba337c44SJed Brown   PetscFunctionReturn(0);
2106ba337c44SJed Brown }
2107284134d9SBarry Smith 
2108a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
2109150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
2110a9fe9ddaSSatish Balay {
2111a9fe9ddaSSatish Balay   PetscErrorCode ierr;
2112a9fe9ddaSSatish Balay 
2113a9fe9ddaSSatish Balay   PetscFunctionBegin;
2114a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
21153ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2116a9fe9ddaSSatish Balay     ierr = MatMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
21173ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2118a9fe9ddaSSatish Balay   }
21193ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2120ca15aa20SStefano Zampini   if ((*C)->ops->matmultnumeric) {
2121ca15aa20SStefano Zampini     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
2122ca15aa20SStefano Zampini   } else {
2123a9fe9ddaSSatish Balay     ierr = MatMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
2124ca15aa20SStefano Zampini   }
21253ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2126a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2127a9fe9ddaSSatish Balay }
2128a9fe9ddaSSatish Balay 
2129a9fe9ddaSSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
2130a9fe9ddaSSatish Balay {
2131ee16a9a1SHong Zhang   PetscErrorCode ierr;
2132d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
2133ee16a9a1SHong Zhang   Mat            Cmat;
2134ca15aa20SStefano Zampini   PetscBool      flg;
2135a9fe9ddaSSatish Balay 
2136ee16a9a1SHong Zhang   PetscFunctionBegin;
2137ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
2138ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
2139ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
2140ca15aa20SStefano Zampini   ierr = MatSetType(Cmat,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
21410298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
2142ee16a9a1SHong Zhang   *C   = Cmat;
2143ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2144ee16a9a1SHong Zhang }
2145a9fe9ddaSSatish Balay 
2146a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2147a9fe9ddaSSatish Balay {
214852c5f739Sprj-   Mat_SeqDense       *a,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
21490805154bSBarry Smith   PetscBLASInt       m,n,k;
2150ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2151ca15aa20SStefano Zampini   PetscScalar       *cv;
2152a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2153fd4e9aacSBarry Smith   PetscBool         flg;
2154c2916339SPierre Jolivet   PetscErrorCode    (*numeric)(Mat,Mat,Mat)=NULL;
2155c2916339SPierre Jolivet   PetscErrorCode    ierr;
2156a9fe9ddaSSatish Balay 
2157a9fe9ddaSSatish Balay   PetscFunctionBegin;
2158fd4e9aacSBarry Smith   /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/
2159fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
2160c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqAIJ_SeqDense;
2161a001520aSPierre Jolivet   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQBAIJ,&flg);CHKERRQ(ierr);
2162c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqBAIJ_SeqDense;
2163c2916339SPierre Jolivet   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQSBAIJ,&flg);CHKERRQ(ierr);
2164c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqSBAIJ_SeqDense;
216552c5f739Sprj-   ierr = PetscObjectTypeCompare((PetscObject)A,MATNEST,&flg);CHKERRQ(ierr);
2166c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_Nest_Dense;
2167c2916339SPierre Jolivet   if (numeric) {
2168c2916339SPierre Jolivet     C->ops->matmultnumeric = numeric;
2169c2916339SPierre Jolivet     ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
217052c5f739Sprj-     PetscFunctionReturn(0);
217152c5f739Sprj-   }
217252c5f739Sprj-   a = (Mat_SeqDense*)A->data;
21738208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
21748208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2175c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
217649d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
2177ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
2178ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
2179ca15aa20SStefano Zampini   ierr = MatDenseGetArray(C,&cv);CHKERRQ(ierr);
2180ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
2181ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2182ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
2183ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
2184ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(C,&cv);CHKERRQ(ierr);
2185a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2186a9fe9ddaSSatish Balay }
2187a9fe9ddaSSatish Balay 
218869f65d41SStefano Zampini PetscErrorCode MatMatTransposeMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
218969f65d41SStefano Zampini {
219069f65d41SStefano Zampini   PetscErrorCode ierr;
219169f65d41SStefano Zampini 
219269f65d41SStefano Zampini   PetscFunctionBegin;
219369f65d41SStefano Zampini   if (scall == MAT_INITIAL_MATRIX) {
219469f65d41SStefano Zampini     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
219569f65d41SStefano Zampini     ierr = MatMatTransposeMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
219669f65d41SStefano Zampini     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
219769f65d41SStefano Zampini   }
219869f65d41SStefano Zampini   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
219969f65d41SStefano Zampini   ierr = MatMatTransposeMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
220069f65d41SStefano Zampini   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
220169f65d41SStefano Zampini   PetscFunctionReturn(0);
220269f65d41SStefano Zampini }
220369f65d41SStefano Zampini 
220469f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
220569f65d41SStefano Zampini {
220669f65d41SStefano Zampini   PetscErrorCode ierr;
220769f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
220869f65d41SStefano Zampini   Mat            Cmat;
2209ca15aa20SStefano Zampini   PetscBool      flg;
221069f65d41SStefano Zampini 
221169f65d41SStefano Zampini   PetscFunctionBegin;
221269f65d41SStefano Zampini   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
221369f65d41SStefano Zampini   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
2214ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
2215ca15aa20SStefano Zampini   ierr = MatSetType(Cmat,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
221669f65d41SStefano Zampini   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
221769f65d41SStefano Zampini   *C   = Cmat;
221869f65d41SStefano Zampini   PetscFunctionReturn(0);
221969f65d41SStefano Zampini }
222069f65d41SStefano Zampini 
222169f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
222269f65d41SStefano Zampini {
222369f65d41SStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
222469f65d41SStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
222569f65d41SStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
222669f65d41SStefano Zampini   PetscBLASInt   m,n,k;
222769f65d41SStefano Zampini   PetscScalar    _DOne=1.0,_DZero=0.0;
222869f65d41SStefano Zampini   PetscErrorCode ierr;
222969f65d41SStefano Zampini 
223069f65d41SStefano Zampini   PetscFunctionBegin;
223149d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
223249d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
223369f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
223449d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
223569f65d41SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2236ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
223769f65d41SStefano Zampini   PetscFunctionReturn(0);
223869f65d41SStefano Zampini }
223969f65d41SStefano Zampini 
224075648e8dSHong Zhang PetscErrorCode MatTransposeMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
2241a9fe9ddaSSatish Balay {
2242a9fe9ddaSSatish Balay   PetscErrorCode ierr;
2243a9fe9ddaSSatish Balay 
2244a9fe9ddaSSatish Balay   PetscFunctionBegin;
2245a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
22463ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
224775648e8dSHong Zhang     ierr = MatTransposeMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
22483ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2249a9fe9ddaSSatish Balay   }
22503ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
225175648e8dSHong Zhang   ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
22523ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2253a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2254a9fe9ddaSSatish Balay }
2255a9fe9ddaSSatish Balay 
225675648e8dSHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
2257a9fe9ddaSSatish Balay {
2258ee16a9a1SHong Zhang   PetscErrorCode ierr;
2259d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
2260ee16a9a1SHong Zhang   Mat            Cmat;
2261ca15aa20SStefano Zampini   PetscBool      flg;
2262a9fe9ddaSSatish Balay 
2263ee16a9a1SHong Zhang   PetscFunctionBegin;
2264ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
2265ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
2266ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
2267ca15aa20SStefano Zampini   ierr = MatSetType(Cmat,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
22680298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
2269ee16a9a1SHong Zhang   *C   = Cmat;
2270ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2271ee16a9a1SHong Zhang }
2272a9fe9ddaSSatish Balay 
227375648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2274a9fe9ddaSSatish Balay {
2275a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2276a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2277a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
22780805154bSBarry Smith   PetscBLASInt   m,n,k;
2279a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
2280c5df96a5SBarry Smith   PetscErrorCode ierr;
2281a9fe9ddaSSatish Balay 
2282a9fe9ddaSSatish Balay   PetscFunctionBegin;
22838208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
22848208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2285c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
228649d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
22875ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2288ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2289a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2290a9fe9ddaSSatish Balay }
2291985db425SBarry Smith 
2292e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2293985db425SBarry Smith {
2294985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2295985db425SBarry Smith   PetscErrorCode     ierr;
2296d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2297985db425SBarry Smith   PetscScalar        *x;
2298ca15aa20SStefano Zampini   const PetscScalar *aa;
2299985db425SBarry Smith 
2300985db425SBarry Smith   PetscFunctionBegin;
2301e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2302985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2303985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2304ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2305e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2306985db425SBarry Smith   for (i=0; i<m; i++) {
2307985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2308985db425SBarry Smith     for (j=1; j<n; j++) {
2309ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2310985db425SBarry Smith     }
2311985db425SBarry Smith   }
2312ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2313985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2314985db425SBarry Smith   PetscFunctionReturn(0);
2315985db425SBarry Smith }
2316985db425SBarry Smith 
2317e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2318985db425SBarry Smith {
2319985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2320985db425SBarry Smith   PetscErrorCode    ierr;
2321d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2322985db425SBarry Smith   PetscScalar       *x;
2323985db425SBarry Smith   PetscReal         atmp;
2324ca15aa20SStefano Zampini   const PetscScalar *aa;
2325985db425SBarry Smith 
2326985db425SBarry Smith   PetscFunctionBegin;
2327e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2328985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2329985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2330ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2331e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2332985db425SBarry Smith   for (i=0; i<m; i++) {
23339189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2334985db425SBarry Smith     for (j=1; j<n; j++) {
2335ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2336985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2337985db425SBarry Smith     }
2338985db425SBarry Smith   }
2339ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2340985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2341985db425SBarry Smith   PetscFunctionReturn(0);
2342985db425SBarry Smith }
2343985db425SBarry Smith 
2344e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2345985db425SBarry Smith {
2346985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2347985db425SBarry Smith   PetscErrorCode    ierr;
2348d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2349985db425SBarry Smith   PetscScalar       *x;
2350ca15aa20SStefano Zampini   const PetscScalar *aa;
2351985db425SBarry Smith 
2352985db425SBarry Smith   PetscFunctionBegin;
2353e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2354ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2355985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2356985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2357e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2358985db425SBarry Smith   for (i=0; i<m; i++) {
2359985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2360985db425SBarry Smith     for (j=1; j<n; j++) {
2361ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2362985db425SBarry Smith     }
2363985db425SBarry Smith   }
2364985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2365ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2366985db425SBarry Smith   PetscFunctionReturn(0);
2367985db425SBarry Smith }
2368985db425SBarry Smith 
2369e0877f53SBarry Smith static PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
23708d0534beSBarry Smith {
23718d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
23728d0534beSBarry Smith   PetscErrorCode    ierr;
23738d0534beSBarry Smith   PetscScalar       *x;
2374ca15aa20SStefano Zampini   const PetscScalar *aa;
23758d0534beSBarry Smith 
23768d0534beSBarry Smith   PetscFunctionBegin;
2377e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2378ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
23798d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2380ca15aa20SStefano Zampini   ierr = PetscArraycpy(x,aa+col*a->lda,A->rmap->n);CHKERRQ(ierr);
23818d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2382ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
23838d0534beSBarry Smith   PetscFunctionReturn(0);
23848d0534beSBarry Smith }
23858d0534beSBarry Smith 
238652c5f739Sprj- PETSC_INTERN PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
23870716a85fSBarry Smith {
23880716a85fSBarry Smith   PetscErrorCode    ierr;
23890716a85fSBarry Smith   PetscInt          i,j,m,n;
23901683a169SBarry Smith   const PetscScalar *a;
23910716a85fSBarry Smith 
23920716a85fSBarry Smith   PetscFunctionBegin;
23930716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2394580bdb30SBarry Smith   ierr = PetscArrayzero(norms,n);CHKERRQ(ierr);
23951683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&a);CHKERRQ(ierr);
23960716a85fSBarry Smith   if (type == NORM_2) {
23970716a85fSBarry Smith     for (i=0; i<n; i++) {
23980716a85fSBarry Smith       for (j=0; j<m; j++) {
23990716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
24000716a85fSBarry Smith       }
24010716a85fSBarry Smith       a += m;
24020716a85fSBarry Smith     }
24030716a85fSBarry Smith   } else if (type == NORM_1) {
24040716a85fSBarry Smith     for (i=0; i<n; i++) {
24050716a85fSBarry Smith       for (j=0; j<m; j++) {
24060716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
24070716a85fSBarry Smith       }
24080716a85fSBarry Smith       a += m;
24090716a85fSBarry Smith     }
24100716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
24110716a85fSBarry Smith     for (i=0; i<n; i++) {
24120716a85fSBarry Smith       for (j=0; j<m; j++) {
24130716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
24140716a85fSBarry Smith       }
24150716a85fSBarry Smith       a += m;
24160716a85fSBarry Smith     }
2417ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
24181683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&a);CHKERRQ(ierr);
24190716a85fSBarry Smith   if (type == NORM_2) {
24208f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
24210716a85fSBarry Smith   }
24220716a85fSBarry Smith   PetscFunctionReturn(0);
24230716a85fSBarry Smith }
24240716a85fSBarry Smith 
242573a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
242673a71a0fSBarry Smith {
242773a71a0fSBarry Smith   PetscErrorCode ierr;
242873a71a0fSBarry Smith   PetscScalar    *a;
242973a71a0fSBarry Smith   PetscInt       m,n,i;
243073a71a0fSBarry Smith 
243173a71a0fSBarry Smith   PetscFunctionBegin;
243273a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
24338c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
243473a71a0fSBarry Smith   for (i=0; i<m*n; i++) {
243573a71a0fSBarry Smith     ierr = PetscRandomGetValue(rctx,a+i);CHKERRQ(ierr);
243673a71a0fSBarry Smith   }
24378c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
243873a71a0fSBarry Smith   PetscFunctionReturn(0);
243973a71a0fSBarry Smith }
244073a71a0fSBarry Smith 
24413b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
24423b49f96aSBarry Smith {
24433b49f96aSBarry Smith   PetscFunctionBegin;
24443b49f96aSBarry Smith   *missing = PETSC_FALSE;
24453b49f96aSBarry Smith   PetscFunctionReturn(0);
24463b49f96aSBarry Smith }
244773a71a0fSBarry Smith 
2448ca15aa20SStefano Zampini /* vals is not const */
2449af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
245086aefd0dSHong Zhang {
2451ca15aa20SStefano Zampini   PetscErrorCode ierr;
245286aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2453ca15aa20SStefano Zampini   PetscScalar    *v;
245486aefd0dSHong Zhang 
245586aefd0dSHong Zhang   PetscFunctionBegin;
245686aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2457ca15aa20SStefano Zampini   ierr  = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2458ca15aa20SStefano Zampini   *vals = v+col*a->lda;
2459ca15aa20SStefano Zampini   ierr  = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
246086aefd0dSHong Zhang   PetscFunctionReturn(0);
246186aefd0dSHong Zhang }
246286aefd0dSHong Zhang 
2463af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
246486aefd0dSHong Zhang {
246586aefd0dSHong Zhang   PetscFunctionBegin;
246686aefd0dSHong Zhang   *vals = 0; /* user cannot accidently use the array later */
246786aefd0dSHong Zhang   PetscFunctionReturn(0);
246886aefd0dSHong Zhang }
2469abc3b08eSStefano Zampini 
2470289bc588SBarry Smith /* -------------------------------------------------------------------*/
2471a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2472905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2473905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2474905e6a2fSBarry Smith                                         MatMult_SeqDense,
247597304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
24767c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
24777c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2478db4efbfdSBarry Smith                                         0,
2479db4efbfdSBarry Smith                                         0,
2480db4efbfdSBarry Smith                                         0,
2481db4efbfdSBarry Smith                                 /* 10*/ 0,
2482905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2483905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
248441f059aeSBarry Smith                                         MatSOR_SeqDense,
2485ec8511deSBarry Smith                                         MatTranspose_SeqDense,
248697304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2487905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2488905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2489905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2490905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2491c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2492c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2493905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2494905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2495d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2496db4efbfdSBarry Smith                                         0,
2497db4efbfdSBarry Smith                                         0,
2498db4efbfdSBarry Smith                                         0,
2499db4efbfdSBarry Smith                                         0,
25004994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2501273d9f13SBarry Smith                                         0,
2502905e6a2fSBarry Smith                                         0,
250373a71a0fSBarry Smith                                         0,
250473a71a0fSBarry Smith                                         0,
2505d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2506a5ae1ecdSBarry Smith                                         0,
2507a5ae1ecdSBarry Smith                                         0,
2508a5ae1ecdSBarry Smith                                         0,
2509a5ae1ecdSBarry Smith                                         0,
2510d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
25117dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2512a5ae1ecdSBarry Smith                                         0,
25134b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2514a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2515d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2516a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
25177d68702bSBarry Smith                                         MatShift_Basic,
2518a5ae1ecdSBarry Smith                                         0,
25193f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
252073a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2521a5ae1ecdSBarry Smith                                         0,
2522a5ae1ecdSBarry Smith                                         0,
2523a5ae1ecdSBarry Smith                                         0,
2524a5ae1ecdSBarry Smith                                         0,
2525d519adbfSMatthew Knepley                                 /* 54*/ 0,
2526a5ae1ecdSBarry Smith                                         0,
2527a5ae1ecdSBarry Smith                                         0,
2528a5ae1ecdSBarry Smith                                         0,
2529a5ae1ecdSBarry Smith                                         0,
2530d519adbfSMatthew Knepley                                 /* 59*/ 0,
2531e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2532e03a110bSBarry Smith                                         MatView_SeqDense,
2533357abbc8SBarry Smith                                         0,
253497304618SKris Buschelman                                         0,
2535d519adbfSMatthew Knepley                                 /* 64*/ 0,
253697304618SKris Buschelman                                         0,
253797304618SKris Buschelman                                         0,
253897304618SKris Buschelman                                         0,
253997304618SKris Buschelman                                         0,
2540d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
254197304618SKris Buschelman                                         0,
254297304618SKris Buschelman                                         0,
254397304618SKris Buschelman                                         0,
254497304618SKris Buschelman                                         0,
2545d519adbfSMatthew Knepley                                 /* 74*/ 0,
254697304618SKris Buschelman                                         0,
254797304618SKris Buschelman                                         0,
254897304618SKris Buschelman                                         0,
254997304618SKris Buschelman                                         0,
2550d519adbfSMatthew Knepley                                 /* 79*/ 0,
255197304618SKris Buschelman                                         0,
255297304618SKris Buschelman                                         0,
255397304618SKris Buschelman                                         0,
25545bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2555865e5f61SKris Buschelman                                         0,
25561cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2557865e5f61SKris Buschelman                                         0,
2558865e5f61SKris Buschelman                                         0,
2559865e5f61SKris Buschelman                                         0,
2560d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqDense_SeqDense,
2561a9fe9ddaSSatish Balay                                         MatMatMultSymbolic_SeqDense_SeqDense,
2562a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2563abc3b08eSStefano Zampini                                         MatPtAP_SeqDense_SeqDense,
2564abc3b08eSStefano Zampini                                         MatPtAPSymbolic_SeqDense_SeqDense,
2565abc3b08eSStefano Zampini                                 /* 94*/ MatPtAPNumeric_SeqDense_SeqDense,
256669f65d41SStefano Zampini                                         MatMatTransposeMult_SeqDense_SeqDense,
256769f65d41SStefano Zampini                                         MatMatTransposeMultSymbolic_SeqDense_SeqDense,
256869f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2569284134d9SBarry Smith                                         0,
2570d519adbfSMatthew Knepley                                 /* 99*/ 0,
2571284134d9SBarry Smith                                         0,
2572284134d9SBarry Smith                                         0,
2573ba337c44SJed Brown                                         MatConjugate_SeqDense,
2574f73d5cc4SBarry Smith                                         0,
2575ba337c44SJed Brown                                 /*104*/ 0,
2576ba337c44SJed Brown                                         MatRealPart_SeqDense,
2577ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2578985db425SBarry Smith                                         0,
2579985db425SBarry Smith                                         0,
25808208b9aeSStefano Zampini                                 /*109*/ 0,
2581985db425SBarry Smith                                         0,
25828d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2583aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
25843b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2585aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2586aabbc4fbSShri Abhyankar                                         0,
2587aabbc4fbSShri Abhyankar                                         0,
2588aabbc4fbSShri Abhyankar                                         0,
2589aabbc4fbSShri Abhyankar                                         0,
2590aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2591aabbc4fbSShri Abhyankar                                         0,
2592aabbc4fbSShri Abhyankar                                         0,
25930716a85fSBarry Smith                                         0,
25940716a85fSBarry Smith                                         0,
25950716a85fSBarry Smith                                 /*124*/ 0,
25965df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
25975df89d91SHong Zhang                                         0,
25985df89d91SHong Zhang                                         0,
25995df89d91SHong Zhang                                         0,
26005df89d91SHong Zhang                                 /*129*/ 0,
260175648e8dSHong Zhang                                         MatTransposeMatMult_SeqDense_SeqDense,
260275648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqDense_SeqDense,
260375648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
26043964eb88SJed Brown                                         0,
26053964eb88SJed Brown                                 /*134*/ 0,
26063964eb88SJed Brown                                         0,
26073964eb88SJed Brown                                         0,
26083964eb88SJed Brown                                         0,
26093964eb88SJed Brown                                         0,
26103964eb88SJed Brown                                 /*139*/ 0,
2611f9426fe0SMark Adams                                         0,
2612d528f656SJakub Kruzik                                         0,
2613d528f656SJakub Kruzik                                         0,
2614d528f656SJakub Kruzik                                         0,
2615d528f656SJakub Kruzik                                 /*144*/ MatCreateMPIMatConcatenateSeqMat_SeqDense
2616985db425SBarry Smith };
261790ace30eSBarry Smith 
26184b828684SBarry Smith /*@C
2619fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2620d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2621d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2622289bc588SBarry Smith 
2623d083f849SBarry Smith    Collective
2624db81eaa0SLois Curfman McInnes 
262520563c6bSBarry Smith    Input Parameters:
2626db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
26270c775827SLois Curfman McInnes .  m - number of rows
262818f449edSLois Curfman McInnes .  n - number of columns
26290298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2630dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
263120563c6bSBarry Smith 
263220563c6bSBarry Smith    Output Parameter:
263344cd7ae7SLois Curfman McInnes .  A - the matrix
263420563c6bSBarry Smith 
2635b259b22eSLois Curfman McInnes    Notes:
263618f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
263718f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
26380298fd71SBarry Smith    set data=NULL.
263918f449edSLois Curfman McInnes 
2640027ccd11SLois Curfman McInnes    Level: intermediate
2641027ccd11SLois Curfman McInnes 
264269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
264320563c6bSBarry Smith @*/
26447087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2645289bc588SBarry Smith {
2646dfbe8321SBarry Smith   PetscErrorCode ierr;
26473b2fbd54SBarry Smith 
26483a40ed3dSBarry Smith   PetscFunctionBegin;
2649f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2650f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2651273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2652273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2653273d9f13SBarry Smith   PetscFunctionReturn(0);
2654273d9f13SBarry Smith }
2655273d9f13SBarry Smith 
2656273d9f13SBarry Smith /*@C
2657273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2658273d9f13SBarry Smith 
2659d083f849SBarry Smith    Collective
2660273d9f13SBarry Smith 
2661273d9f13SBarry Smith    Input Parameters:
26621c4f3114SJed Brown +  B - the matrix
26630298fd71SBarry Smith -  data - the array (or NULL)
2664273d9f13SBarry Smith 
2665273d9f13SBarry Smith    Notes:
2666273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2667273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2668284134d9SBarry Smith    need not call this routine.
2669273d9f13SBarry Smith 
2670273d9f13SBarry Smith    Level: intermediate
2671273d9f13SBarry Smith 
267269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA()
2673867c911aSBarry Smith 
2674273d9f13SBarry Smith @*/
26757087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2676273d9f13SBarry Smith {
26774ac538c5SBarry Smith   PetscErrorCode ierr;
2678a23d5eceSKris Buschelman 
2679a23d5eceSKris Buschelman   PetscFunctionBegin;
26804ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2681a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2682a23d5eceSKris Buschelman }
2683a23d5eceSKris Buschelman 
26847087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2685a23d5eceSKris Buschelman {
2686273d9f13SBarry Smith   Mat_SeqDense   *b;
2687dfbe8321SBarry Smith   PetscErrorCode ierr;
2688273d9f13SBarry Smith 
2689273d9f13SBarry Smith   PetscFunctionBegin;
2690273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2691a868139aSShri Abhyankar 
269234ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
269334ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
269434ef9618SShri Abhyankar 
2695273d9f13SBarry Smith   b       = (Mat_SeqDense*)B->data;
269686d161a7SShri Abhyankar   b->Mmax = B->rmap->n;
269786d161a7SShri Abhyankar   b->Nmax = B->cmap->n;
269886d161a7SShri Abhyankar   if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n;
269986d161a7SShri Abhyankar 
2700220afb94SBarry Smith   ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr);
27019e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
27029e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2703e92229d0SSatish Balay     ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr);
27043bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
27052205254eSKarl Rupp 
27069e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2707273d9f13SBarry Smith   } else { /* user-allocated storage */
27089e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2709273d9f13SBarry Smith     b->v          = data;
2710273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2711273d9f13SBarry Smith   }
27120450473dSBarry Smith   B->assembled = PETSC_TRUE;
2713273d9f13SBarry Smith   PetscFunctionReturn(0);
2714273d9f13SBarry Smith }
2715273d9f13SBarry Smith 
271665b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2717cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
27188baccfbdSHong Zhang {
2719d77f618aSHong Zhang   Mat               mat_elemental;
2720d77f618aSHong Zhang   PetscErrorCode    ierr;
27211683a169SBarry Smith   const PetscScalar *array;
27221683a169SBarry Smith   PetscScalar       *v_colwise;
2723d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2724d77f618aSHong Zhang 
27258baccfbdSHong Zhang   PetscFunctionBegin;
2726d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
27271683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&array);CHKERRQ(ierr);
2728d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2729d77f618aSHong Zhang   k = 0;
2730d77f618aSHong Zhang   for (j=0; j<N; j++) {
2731d77f618aSHong Zhang     cols[j] = j;
2732d77f618aSHong Zhang     for (i=0; i<M; i++) {
2733d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2734d77f618aSHong Zhang     }
2735d77f618aSHong Zhang   }
2736d77f618aSHong Zhang   for (i=0; i<M; i++) {
2737d77f618aSHong Zhang     rows[i] = i;
2738d77f618aSHong Zhang   }
27391683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&array);CHKERRQ(ierr);
2740d77f618aSHong Zhang 
2741d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2742d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2743d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2744d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2745d77f618aSHong Zhang 
2746d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2747d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2748d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2749d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2750d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2751d77f618aSHong Zhang 
2752511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
275328be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2754d77f618aSHong Zhang   } else {
2755d77f618aSHong Zhang     *newmat = mat_elemental;
2756d77f618aSHong Zhang   }
27578baccfbdSHong Zhang   PetscFunctionReturn(0);
27588baccfbdSHong Zhang }
275965b80a83SHong Zhang #endif
27608baccfbdSHong Zhang 
27611b807ce4Svictorle /*@C
27621b807ce4Svictorle   MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array
27631b807ce4Svictorle 
27641b807ce4Svictorle   Input parameter:
27651b807ce4Svictorle + A - the matrix
27661b807ce4Svictorle - lda - the leading dimension
27671b807ce4Svictorle 
27681b807ce4Svictorle   Notes:
2769867c911aSBarry Smith   This routine is to be used in conjunction with MatSeqDenseSetPreallocation();
27701b807ce4Svictorle   it asserts that the preallocation has a leading dimension (the LDA parameter
27711b807ce4Svictorle   of Blas and Lapack fame) larger than M, the first dimension of the matrix.
27721b807ce4Svictorle 
27731b807ce4Svictorle   Level: intermediate
27741b807ce4Svictorle 
2775284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize()
2776867c911aSBarry Smith 
27771b807ce4Svictorle @*/
27787087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetLDA(Mat B,PetscInt lda)
27791b807ce4Svictorle {
27801b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
278121a2c019SBarry Smith 
27821b807ce4Svictorle   PetscFunctionBegin;
2783e32f2f54SBarry 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);
27841b807ce4Svictorle   b->lda       = lda;
278521a2c019SBarry Smith   b->changelda = PETSC_FALSE;
278621a2c019SBarry Smith   b->Mmax      = PetscMax(b->Mmax,lda);
27871b807ce4Svictorle   PetscFunctionReturn(0);
27881b807ce4Svictorle }
27891b807ce4Svictorle 
2790d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
2791d528f656SJakub Kruzik {
2792d528f656SJakub Kruzik   PetscErrorCode ierr;
2793d528f656SJakub Kruzik   PetscMPIInt    size;
2794d528f656SJakub Kruzik 
2795d528f656SJakub Kruzik   PetscFunctionBegin;
2796d528f656SJakub Kruzik   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2797d528f656SJakub Kruzik   if (size == 1) {
2798d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
2799d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
2800d528f656SJakub Kruzik     } else {
2801d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2802d528f656SJakub Kruzik     }
2803d528f656SJakub Kruzik   } else {
2804d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
2805d528f656SJakub Kruzik   }
2806d528f656SJakub Kruzik   PetscFunctionReturn(0);
2807d528f656SJakub Kruzik }
2808d528f656SJakub Kruzik 
28090bad9183SKris Buschelman /*MC
2810fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
28110bad9183SKris Buschelman 
28120bad9183SKris Buschelman    Options Database Keys:
28130bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
28140bad9183SKris Buschelman 
28150bad9183SKris Buschelman   Level: beginner
28160bad9183SKris Buschelman 
281789665df3SBarry Smith .seealso: MatCreateSeqDense()
281889665df3SBarry Smith 
28190bad9183SKris Buschelman M*/
2820ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
2821273d9f13SBarry Smith {
2822273d9f13SBarry Smith   Mat_SeqDense   *b;
2823dfbe8321SBarry Smith   PetscErrorCode ierr;
28247c334f02SBarry Smith   PetscMPIInt    size;
2825273d9f13SBarry Smith 
2826273d9f13SBarry Smith   PetscFunctionBegin;
2827ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
2828e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
282955659b69SBarry Smith 
2830b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
2831549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
283244cd7ae7SLois Curfman McInnes   B->data = (void*)b;
283318f449edSLois Curfman McInnes 
2834273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
28354e220ebcSLois Curfman McInnes 
283649a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
2837bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
28388572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2839d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
2840d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
28418572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2842715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2843bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
28448baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
28458baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
28468baccfbdSHong Zhang #endif
28472bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
28482bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA);CHKERRQ(ierr);
2849a4af7ca8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijcusparse_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
28502bf066beSStefano Zampini #endif
2851bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
2852bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaij_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2853a4af7ca8SStefano Zampini #if defined(PETSC_HAVE_VIENNACL)
2854a4af7ca8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijviennacl_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2855a4af7ca8SStefano Zampini #endif
2856bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2857bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2858a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqbaij_seqdense_C",MatMatMult_SeqBAIJ_SeqDense);CHKERRQ(ierr);
2859a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqbaij_seqdense_C",MatMatMultSymbolic_SeqBAIJ_SeqDense);CHKERRQ(ierr);
2860a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqbaij_seqdense_C",MatMatMultNumeric_SeqBAIJ_SeqDense);CHKERRQ(ierr);
2861c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqsbaij_seqdense_C",MatMatMult_SeqSBAIJ_SeqDense);CHKERRQ(ierr);
2862c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqsbaij_seqdense_C",MatMatMultSymbolic_SeqSBAIJ_SeqDense);CHKERRQ(ierr);
2863c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqsbaij_seqdense_C",MatMatMultNumeric_SeqSBAIJ_SeqDense);CHKERRQ(ierr);
2864abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaij_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
28654099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijperm_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
28664099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijperm_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28674099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijperm_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
28684099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijperm_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
2869e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijsell_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2870e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijsell_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2871e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijsell_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2872e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijsell_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
287396e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijmkl_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
287496e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijmkl_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
287596e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijmkl_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
287652c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_nest_seqdense_C",MatMatMult_Nest_Dense);CHKERRQ(ierr);
287752c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_nest_seqdense_C",MatMatMultSymbolic_Nest_Dense);CHKERRQ(ierr);
287852c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_nest_seqdense_C",MatMatMultNumeric_Nest_Dense);CHKERRQ(ierr);
287996e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijmkl_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
288096e6d5c4SRichard Tran Mills 
28813bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaij_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
28823bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28833bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
28844099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijperm_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
28854099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28864099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2887e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijsell_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2888e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2889e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
289096e6d5c4SRichard Tran Mills 
289196e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijmkl_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
289296e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
289396e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2894af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
2895af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
289617667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
28973a40ed3dSBarry Smith   PetscFunctionReturn(0);
2898289bc588SBarry Smith }
289986aefd0dSHong Zhang 
290086aefd0dSHong Zhang /*@C
2901af53bab2SHong 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.
290286aefd0dSHong Zhang 
290386aefd0dSHong Zhang    Not Collective
290486aefd0dSHong Zhang 
290586aefd0dSHong Zhang    Input Parameter:
290686aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
290786aefd0dSHong Zhang -  col - column index
290886aefd0dSHong Zhang 
290986aefd0dSHong Zhang    Output Parameter:
291086aefd0dSHong Zhang .  vals - pointer to the data
291186aefd0dSHong Zhang 
291286aefd0dSHong Zhang    Level: intermediate
291386aefd0dSHong Zhang 
291486aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
291586aefd0dSHong Zhang @*/
291686aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
291786aefd0dSHong Zhang {
291886aefd0dSHong Zhang   PetscErrorCode ierr;
291986aefd0dSHong Zhang 
292086aefd0dSHong Zhang   PetscFunctionBegin;
292186aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
292286aefd0dSHong Zhang   PetscFunctionReturn(0);
292386aefd0dSHong Zhang }
292486aefd0dSHong Zhang 
292586aefd0dSHong Zhang /*@C
292686aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
292786aefd0dSHong Zhang 
292886aefd0dSHong Zhang    Not Collective
292986aefd0dSHong Zhang 
293086aefd0dSHong Zhang    Input Parameter:
293186aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
293286aefd0dSHong Zhang 
293386aefd0dSHong Zhang    Output Parameter:
293486aefd0dSHong Zhang .  vals - pointer to the data
293586aefd0dSHong Zhang 
293686aefd0dSHong Zhang    Level: intermediate
293786aefd0dSHong Zhang 
293886aefd0dSHong Zhang .seealso: MatDenseGetColumn()
293986aefd0dSHong Zhang @*/
294086aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
294186aefd0dSHong Zhang {
294286aefd0dSHong Zhang   PetscErrorCode ierr;
294386aefd0dSHong Zhang 
294486aefd0dSHong Zhang   PetscFunctionBegin;
294586aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
294686aefd0dSHong Zhang   PetscFunctionReturn(0);
294786aefd0dSHong Zhang }
2948