xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 18992e5d44eadf48aacf2808ebf9acfbbacf9355)
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);
1604222ddf1SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"Must call MatPtAPSymbolic_SeqDense_SeqDense() first");
161abc3b08eSStefano Zampini   PetscFunctionReturn(0);
162abc3b08eSStefano Zampini }
163abc3b08eSStefano Zampini 
1644222ddf1SHong Zhang PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat C)
165abc3b08eSStefano Zampini {
166abc3b08eSStefano Zampini   Mat_SeqDense   *c;
167ca15aa20SStefano Zampini   PetscBool      flg;
168abc3b08eSStefano Zampini   PetscErrorCode ierr;
169abc3b08eSStefano Zampini 
170abc3b08eSStefano Zampini   PetscFunctionBegin;
171ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)P,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
1724222ddf1SHong Zhang   ierr = MatSetSizes(C,P->cmap->n,P->cmap->n,P->cmap->N,P->cmap->N);CHKERRQ(ierr);
1734222ddf1SHong Zhang   ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
1744222ddf1SHong Zhang   ierr = MatSeqDenseSetPreallocation(C,NULL);CHKERRQ(ierr);
1754222ddf1SHong Zhang   c    = (Mat_SeqDense*)C->data;
176ca15aa20SStefano Zampini   ierr = MatCreate(PetscObjectComm((PetscObject)A),&c->ptapwork);CHKERRQ(ierr);
177ca15aa20SStefano Zampini   ierr = MatSetSizes(c->ptapwork,A->rmap->n,P->cmap->n,A->rmap->N,P->cmap->N);CHKERRQ(ierr);
178ca15aa20SStefano Zampini   ierr = MatSetType(c->ptapwork,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
179ca15aa20SStefano Zampini   ierr = MatSeqDenseSetPreallocation(c->ptapwork,NULL);CHKERRQ(ierr);
180abc3b08eSStefano Zampini   PetscFunctionReturn(0);
181abc3b08eSStefano Zampini }
182abc3b08eSStefano Zampini 
183cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
184b49cda9fSStefano Zampini {
185a13144ffSStefano Zampini   Mat            B = NULL;
186b49cda9fSStefano Zampini   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
187b49cda9fSStefano Zampini   Mat_SeqDense   *b;
188b49cda9fSStefano Zampini   PetscErrorCode ierr;
189b49cda9fSStefano Zampini   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i;
190b49cda9fSStefano Zampini   MatScalar      *av=a->a;
191a13144ffSStefano Zampini   PetscBool      isseqdense;
192b49cda9fSStefano Zampini 
193b49cda9fSStefano Zampini   PetscFunctionBegin;
194a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
195a13144ffSStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense);CHKERRQ(ierr);
196a32993e3SJed Brown     if (!isseqdense) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type_name);
197a13144ffSStefano Zampini   }
198a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
199b49cda9fSStefano Zampini     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
200b49cda9fSStefano Zampini     ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
201b49cda9fSStefano Zampini     ierr = MatSetType(B,MATSEQDENSE);CHKERRQ(ierr);
202b49cda9fSStefano Zampini     ierr = MatSeqDenseSetPreallocation(B,NULL);CHKERRQ(ierr);
203b49cda9fSStefano Zampini     b    = (Mat_SeqDense*)(B->data);
204a13144ffSStefano Zampini   } else {
205a13144ffSStefano Zampini     b    = (Mat_SeqDense*)((*newmat)->data);
206580bdb30SBarry Smith     ierr = PetscArrayzero(b->v,m*n);CHKERRQ(ierr);
207a13144ffSStefano Zampini   }
208b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
209b49cda9fSStefano Zampini     PetscInt j;
210b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
211b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
212b49cda9fSStefano Zampini       aj++;
213b49cda9fSStefano Zampini       av++;
214b49cda9fSStefano Zampini     }
215b49cda9fSStefano Zampini     ai++;
216b49cda9fSStefano Zampini   }
217b49cda9fSStefano Zampini 
218511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
219a13144ffSStefano Zampini     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
220a13144ffSStefano Zampini     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22128be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
222b49cda9fSStefano Zampini   } else {
223a13144ffSStefano Zampini     if (B) *newmat = B;
224a13144ffSStefano Zampini     ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
225a13144ffSStefano Zampini     ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
226b49cda9fSStefano Zampini   }
227b49cda9fSStefano Zampini   PetscFunctionReturn(0);
228b49cda9fSStefano Zampini }
229b49cda9fSStefano Zampini 
230cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
2316a63e612SBarry Smith {
2326a63e612SBarry Smith   Mat            B;
2336a63e612SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2346a63e612SBarry Smith   PetscErrorCode ierr;
2359399e1b8SMatthew G. Knepley   PetscInt       i, j;
2369399e1b8SMatthew G. Knepley   PetscInt       *rows, *nnz;
2379399e1b8SMatthew G. Knepley   MatScalar      *aa = a->v, *vals;
2386a63e612SBarry Smith 
2396a63e612SBarry Smith   PetscFunctionBegin;
240ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
2416a63e612SBarry Smith   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
2426a63e612SBarry Smith   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
2439399e1b8SMatthew G. Knepley   ierr = PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals);CHKERRQ(ierr);
2449399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2459399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) ++nnz[i];
2466a63e612SBarry Smith     aa += a->lda;
2476a63e612SBarry Smith   }
2489399e1b8SMatthew G. Knepley   ierr = MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz);CHKERRQ(ierr);
2499399e1b8SMatthew G. Knepley   aa = a->v;
2509399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2519399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2529399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) {rows[numRows] = i; vals[numRows++] = aa[i];}
2539399e1b8SMatthew G. Knepley     ierr = MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr);
2549399e1b8SMatthew G. Knepley     aa  += a->lda;
2559399e1b8SMatthew G. Knepley   }
2569399e1b8SMatthew G. Knepley   ierr = PetscFree3(rows,nnz,vals);CHKERRQ(ierr);
2576a63e612SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2586a63e612SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2596a63e612SBarry Smith 
260511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
26128be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
2626a63e612SBarry Smith   } else {
2636a63e612SBarry Smith     *newmat = B;
2646a63e612SBarry Smith   }
2656a63e612SBarry Smith   PetscFunctionReturn(0);
2666a63e612SBarry Smith }
2676a63e612SBarry Smith 
268ca15aa20SStefano Zampini PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
2691987afe7SBarry Smith {
2701987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
271ca15aa20SStefano Zampini   const PetscScalar *xv;
272ca15aa20SStefano Zampini   PetscScalar       *yv;
2730805154bSBarry Smith   PetscBLASInt      N,m,ldax,lday,one = 1;
274efee365bSSatish Balay   PetscErrorCode    ierr;
2753a40ed3dSBarry Smith 
2763a40ed3dSBarry Smith   PetscFunctionBegin;
277ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(X,&xv);CHKERRQ(ierr);
278ca15aa20SStefano Zampini   ierr = MatDenseGetArray(Y,&yv);CHKERRQ(ierr);
279c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n*X->cmap->n,&N);CHKERRQ(ierr);
280c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n,&m);CHKERRQ(ierr);
281c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->lda,&ldax);CHKERRQ(ierr);
282c5df96a5SBarry Smith   ierr = PetscBLASIntCast(y->lda,&lday);CHKERRQ(ierr);
283a5ce6ee0Svictorle   if (ldax>m || lday>m) {
284ca15aa20SStefano Zampini     PetscInt j;
285ca15aa20SStefano Zampini 
286d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
287ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&alpha,xv+j*ldax,&one,yv+j*lday,&one));
288a5ce6ee0Svictorle     }
289a5ce6ee0Svictorle   } else {
290ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&alpha,xv,&one,yv,&one));
291a5ce6ee0Svictorle   }
292ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(X,&xv);CHKERRQ(ierr);
293ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(Y,&yv);CHKERRQ(ierr);
2940450473dSBarry Smith   ierr = PetscLogFlops(PetscMax(2*N-1,0));CHKERRQ(ierr);
2953a40ed3dSBarry Smith   PetscFunctionReturn(0);
2961987afe7SBarry Smith }
2971987afe7SBarry Smith 
298e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
299289bc588SBarry Smith {
300ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n*A->cmap->n;
3013a40ed3dSBarry Smith 
3023a40ed3dSBarry Smith   PetscFunctionBegin;
3034e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
304ca15aa20SStefano Zampini   info->nz_allocated      = N;
305ca15aa20SStefano Zampini   info->nz_used           = N;
306ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
307ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
3084e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3097adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3104e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3114e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3124e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3133a40ed3dSBarry Smith   PetscFunctionReturn(0);
314289bc588SBarry Smith }
315289bc588SBarry Smith 
316e0877f53SBarry Smith static PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
31780cd9d93SLois Curfman McInnes {
318273d9f13SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
319ca15aa20SStefano Zampini   PetscScalar    *v;
320efee365bSSatish Balay   PetscErrorCode ierr;
321c5df96a5SBarry Smith   PetscBLASInt   one = 1,j,nz,lda;
32280cd9d93SLois Curfman McInnes 
3233a40ed3dSBarry Smith   PetscFunctionBegin;
324ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
325c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->lda,&lda);CHKERRQ(ierr);
326d0f46423SBarry Smith   if (lda>A->rmap->n) {
327c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n,&nz);CHKERRQ(ierr);
328d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
329ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v+j*lda,&one));
330a5ce6ee0Svictorle     }
331a5ce6ee0Svictorle   } else {
332c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz);CHKERRQ(ierr);
333ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v,&one));
334a5ce6ee0Svictorle   }
335efee365bSSatish Balay   ierr = PetscLogFlops(nz);CHKERRQ(ierr);
336ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
3373a40ed3dSBarry Smith   PetscFunctionReturn(0);
33880cd9d93SLois Curfman McInnes }
33980cd9d93SLois Curfman McInnes 
340e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3411cbb95d3SBarry Smith {
3421cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
343ca15aa20SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
344ca15aa20SStefano Zampini   const PetscScalar *v;
345ca15aa20SStefano Zampini   PetscErrorCode    ierr;
3461cbb95d3SBarry Smith 
3471cbb95d3SBarry Smith   PetscFunctionBegin;
3481cbb95d3SBarry Smith   *fl = PETSC_FALSE;
349d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
350ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
3511cbb95d3SBarry Smith   for (i=0; i<m; i++) {
352ca15aa20SStefano Zampini     for (j=i; j<m; j++) {
3531cbb95d3SBarry Smith       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) PetscFunctionReturn(0);
3541cbb95d3SBarry Smith     }
3551cbb95d3SBarry Smith   }
356ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
3571cbb95d3SBarry Smith   *fl  = PETSC_TRUE;
3581cbb95d3SBarry Smith   PetscFunctionReturn(0);
3591cbb95d3SBarry Smith }
3601cbb95d3SBarry Smith 
361ca15aa20SStefano Zampini PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
362b24902e0SBarry Smith {
363ca15aa20SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
364b24902e0SBarry Smith   PetscErrorCode ierr;
365b24902e0SBarry Smith   PetscInt       lda = (PetscInt)mat->lda,j,m;
366b24902e0SBarry Smith 
367b24902e0SBarry Smith   PetscFunctionBegin;
368aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr);
369aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr);
3700298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr);
371b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
372ca15aa20SStefano Zampini     const PetscScalar *av;
373ca15aa20SStefano Zampini     PetscScalar       *v;
374ca15aa20SStefano Zampini 
375ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
376ca15aa20SStefano Zampini     ierr = MatDenseGetArray(newi,&v);CHKERRQ(ierr);
377d0f46423SBarry Smith     if (lda>A->rmap->n) {
378d0f46423SBarry Smith       m = A->rmap->n;
379d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
380ca15aa20SStefano Zampini         ierr = PetscArraycpy(v+j*m,av+j*lda,m);CHKERRQ(ierr);
381b24902e0SBarry Smith       }
382b24902e0SBarry Smith     } else {
383ca15aa20SStefano Zampini       ierr = PetscArraycpy(v,av,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
384b24902e0SBarry Smith     }
385ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(newi,&v);CHKERRQ(ierr);
386ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
387b24902e0SBarry Smith   }
388b24902e0SBarry Smith   PetscFunctionReturn(0);
389b24902e0SBarry Smith }
390b24902e0SBarry Smith 
391ca15aa20SStefano Zampini PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
39202cad45dSBarry Smith {
3936849ba73SBarry Smith   PetscErrorCode ierr;
39402cad45dSBarry Smith 
3953a40ed3dSBarry Smith   PetscFunctionBegin;
396ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr);
397d0f46423SBarry Smith   ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
3985c9eb25fSBarry Smith   ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
399719d5645SBarry Smith   ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr);
400b24902e0SBarry Smith   PetscFunctionReturn(0);
401b24902e0SBarry Smith }
402b24902e0SBarry Smith 
403e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
404289bc588SBarry Smith {
4054482741eSBarry Smith   MatFactorInfo  info;
406a093e273SMatthew Knepley   PetscErrorCode ierr;
4073a40ed3dSBarry Smith 
4083a40ed3dSBarry Smith   PetscFunctionBegin;
409c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
410ca15aa20SStefano Zampini   ierr = (*fact->ops->lufactor)(fact,0,0,&info);CHKERRQ(ierr);
4113a40ed3dSBarry Smith   PetscFunctionReturn(0);
412289bc588SBarry Smith }
4136ee01492SSatish Balay 
414e0877f53SBarry Smith static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy)
415289bc588SBarry Smith {
416c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
4176849ba73SBarry Smith   PetscErrorCode    ierr;
418f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
419f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
420c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
42167e560aaSBarry Smith 
4223a40ed3dSBarry Smith   PetscFunctionBegin;
423c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
424f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4251ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
426580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
427d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_LU) {
42800121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4298b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
43000121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
431e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
432d5f3da31SBarry Smith   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
433a49dc2a2SStefano Zampini     if (A->spd) {
43400121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4358b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
43600121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
437e32f2f54SBarry Smith       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
438a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
439a49dc2a2SStefano Zampini     } else if (A->hermitian) {
44000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
441a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
44200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
443a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
444a49dc2a2SStefano Zampini #endif
445a49dc2a2SStefano Zampini     } else { /* symmetric case */
44600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
447a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
44800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
449a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
450a49dc2a2SStefano Zampini     }
4512205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
452f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4531ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
454dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
4553a40ed3dSBarry Smith   PetscFunctionReturn(0);
456289bc588SBarry Smith }
4576ee01492SSatish Balay 
458e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X)
45985e2c93fSHong Zhang {
46085e2c93fSHong Zhang   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
46185e2c93fSHong Zhang   PetscErrorCode    ierr;
4621683a169SBarry Smith   const PetscScalar *b;
4631683a169SBarry Smith   PetscScalar       *x;
464efb80c78SLisandro Dalcin   PetscInt          n;
465783b601eSJed Brown   PetscBLASInt      nrhs,info,m;
46685e2c93fSHong Zhang 
46785e2c93fSHong Zhang   PetscFunctionBegin;
468c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
4690298fd71SBarry Smith   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
470c5df96a5SBarry Smith   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
4711683a169SBarry Smith   ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
4728c778c55SBarry Smith   ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr);
47385e2c93fSHong Zhang 
474580bdb30SBarry Smith   ierr = PetscArraycpy(x,b,m*nrhs);CHKERRQ(ierr);
47585e2c93fSHong Zhang 
47685e2c93fSHong Zhang   if (A->factortype == MAT_FACTOR_LU) {
47700121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4788b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
47900121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
48085e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
48185e2c93fSHong Zhang   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
482a49dc2a2SStefano Zampini     if (A->spd) {
48300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4848b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
48500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
48685e2c93fSHong Zhang       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
487a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
488a49dc2a2SStefano Zampini     } else if (A->hermitian) {
48900121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
490a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
49100121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
492a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
493a49dc2a2SStefano Zampini #endif
494a49dc2a2SStefano Zampini     } else { /* symmetric case */
49500121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
496a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
49700121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
498a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
499a49dc2a2SStefano Zampini     }
5002205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
50185e2c93fSHong Zhang 
5021683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
5038c778c55SBarry Smith   ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr);
50485e2c93fSHong Zhang   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
50585e2c93fSHong Zhang   PetscFunctionReturn(0);
50685e2c93fSHong Zhang }
50785e2c93fSHong Zhang 
50800121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
50900121966SStefano Zampini 
510e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
511da3a660dSBarry Smith {
512c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
513dfbe8321SBarry Smith   PetscErrorCode    ierr;
514f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
515f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
516c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
51767e560aaSBarry Smith 
5183a40ed3dSBarry Smith   PetscFunctionBegin;
519c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
520f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5211ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
522580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
5238208b9aeSStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
52400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5258b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
52600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
527e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve");
5288208b9aeSStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
529a49dc2a2SStefano Zampini     if (A->spd) {
53000121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
53100121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
53200121966SStefano Zampini #endif
53300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5348b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
53500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
53600121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
53700121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
53800121966SStefano Zampini #endif
539a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
540a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
541a49dc2a2SStefano Zampini     } else if (A->hermitian) {
54200121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
54300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
54400121966SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
54500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
54600121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
547ae7cfcebSSatish Balay #endif
548a49dc2a2SStefano Zampini     } else { /* symmetric case */
54900121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
550a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
55100121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
552a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
553da3a660dSBarry Smith     }
554a49dc2a2SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
555f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5561ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
557dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
5583a40ed3dSBarry Smith   PetscFunctionReturn(0);
559da3a660dSBarry Smith }
5606ee01492SSatish Balay 
561db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
562db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
563db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
564ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
565db4efbfdSBarry Smith {
566db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
567db4efbfdSBarry Smith   PetscErrorCode ierr;
568db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
569db4efbfdSBarry Smith 
570db4efbfdSBarry Smith   PetscFunctionBegin;
571c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
572c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
573db4efbfdSBarry Smith   if (!mat->pivots) {
5748208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
5753bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
576db4efbfdSBarry Smith   }
577db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
5788e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5798b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
5808e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
5818e57ea43SSatish Balay 
582e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
583e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
5848208b9aeSStefano Zampini 
585db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
5868208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
587db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
588d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
589db4efbfdSBarry Smith 
590f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
591f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
592f6224b95SHong Zhang 
593dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
594db4efbfdSBarry Smith   PetscFunctionReturn(0);
595db4efbfdSBarry Smith }
596db4efbfdSBarry Smith 
597a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
598ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
599db4efbfdSBarry Smith {
600db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
601db4efbfdSBarry Smith   PetscErrorCode ierr;
602c5df96a5SBarry Smith   PetscBLASInt   info,n;
603db4efbfdSBarry Smith 
604db4efbfdSBarry Smith   PetscFunctionBegin;
605c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
606db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
607a49dc2a2SStefano Zampini   if (A->spd) {
60800121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6098b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
61000121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
611a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
612a49dc2a2SStefano Zampini   } else if (A->hermitian) {
613a49dc2a2SStefano Zampini     if (!mat->pivots) {
614a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
615a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
616a49dc2a2SStefano Zampini     }
617a49dc2a2SStefano Zampini     if (!mat->fwork) {
618a49dc2a2SStefano Zampini       PetscScalar dummy;
619a49dc2a2SStefano Zampini 
620a49dc2a2SStefano Zampini       mat->lfwork = -1;
62100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
622a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
62300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
624a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
625a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
626a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
627a49dc2a2SStefano Zampini     }
62800121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
629a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
63000121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
631a49dc2a2SStefano Zampini #endif
632a49dc2a2SStefano Zampini   } else { /* symmetric case */
633a49dc2a2SStefano Zampini     if (!mat->pivots) {
634a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
635a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
636a49dc2a2SStefano Zampini     }
637a49dc2a2SStefano Zampini     if (!mat->fwork) {
638a49dc2a2SStefano Zampini       PetscScalar dummy;
639a49dc2a2SStefano Zampini 
640a49dc2a2SStefano Zampini       mat->lfwork = -1;
64100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
642a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
64300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
644a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
645a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
646a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
647a49dc2a2SStefano Zampini     }
64800121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
649a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
65000121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
651a49dc2a2SStefano Zampini   }
652e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
6538208b9aeSStefano Zampini 
654db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6558208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
656db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
657d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
6582205254eSKarl Rupp 
659f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
660f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
661f6224b95SHong Zhang 
662eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
663db4efbfdSBarry Smith   PetscFunctionReturn(0);
664db4efbfdSBarry Smith }
665db4efbfdSBarry Smith 
666db4efbfdSBarry Smith 
6670481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
668db4efbfdSBarry Smith {
669db4efbfdSBarry Smith   PetscErrorCode ierr;
670db4efbfdSBarry Smith   MatFactorInfo  info;
671db4efbfdSBarry Smith 
672db4efbfdSBarry Smith   PetscFunctionBegin;
673db4efbfdSBarry Smith   info.fill = 1.0;
6742205254eSKarl Rupp 
675c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
676ca15aa20SStefano Zampini   ierr = (*fact->ops->choleskyfactor)(fact,0,&info);CHKERRQ(ierr);
677db4efbfdSBarry Smith   PetscFunctionReturn(0);
678db4efbfdSBarry Smith }
679db4efbfdSBarry Smith 
680ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
681db4efbfdSBarry Smith {
682db4efbfdSBarry Smith   PetscFunctionBegin;
683c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
6841bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
685719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
686bd443b22SStefano Zampini   fact->ops->solve                 = MatSolve_SeqDense;
687bd443b22SStefano Zampini   fact->ops->matsolve              = MatMatSolve_SeqDense;
688bd443b22SStefano Zampini   fact->ops->solvetranspose        = MatSolveTranspose_SeqDense;
689db4efbfdSBarry Smith   PetscFunctionReturn(0);
690db4efbfdSBarry Smith }
691db4efbfdSBarry Smith 
692ca15aa20SStefano Zampini PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
693db4efbfdSBarry Smith {
694db4efbfdSBarry Smith   PetscFunctionBegin;
695b66fe19dSMatthew G Knepley   fact->preallocated           = PETSC_TRUE;
696c3ef05f6SHong Zhang   fact->assembled              = PETSC_TRUE;
697719d5645SBarry Smith   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
698bd443b22SStefano Zampini   fact->ops->solve             = MatSolve_SeqDense;
699bd443b22SStefano Zampini   fact->ops->matsolve          = MatMatSolve_SeqDense;
700bd443b22SStefano Zampini   fact->ops->solvetranspose    = MatSolveTranspose_SeqDense;
701db4efbfdSBarry Smith   PetscFunctionReturn(0);
702db4efbfdSBarry Smith }
703db4efbfdSBarry Smith 
704ca15aa20SStefano Zampini /* uses LAPACK */
705cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
706db4efbfdSBarry Smith {
707db4efbfdSBarry Smith   PetscErrorCode ierr;
708db4efbfdSBarry Smith 
709db4efbfdSBarry Smith   PetscFunctionBegin;
710ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
711db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
712ca15aa20SStefano Zampini   ierr = MatSetType(*fact,MATDENSE);CHKERRQ(ierr);
713db4efbfdSBarry Smith   if (ftype == MAT_FACTOR_LU) {
714db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
715db4efbfdSBarry Smith   } else {
716db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
717db4efbfdSBarry Smith   }
718d5f3da31SBarry Smith   (*fact)->factortype = ftype;
71900c67f3bSHong Zhang 
72000c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
72100c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
722db4efbfdSBarry Smith   PetscFunctionReturn(0);
723db4efbfdSBarry Smith }
724db4efbfdSBarry Smith 
725289bc588SBarry Smith /* ------------------------------------------------------------------*/
726e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
727289bc588SBarry Smith {
728c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
729d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
730d9ca1df4SBarry Smith   const PetscScalar *b;
731dfbe8321SBarry Smith   PetscErrorCode    ierr;
732d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
733c5df96a5SBarry Smith   PetscBLASInt      o = 1,bm;
734289bc588SBarry Smith 
7353a40ed3dSBarry Smith   PetscFunctionBegin;
736ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
737c70f7ee4SJunchao Zhang   if (A->offloadmask == PETSC_OFFLOAD_GPU) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
738ca15aa20SStefano Zampini #endif
739422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
740c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
741289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
7423bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
7432dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
744289bc588SBarry Smith   }
7451ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
746d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
747b965ef7fSBarry Smith   its  = its*lits;
748e32f2f54SBarry 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);
749289bc588SBarry Smith   while (its--) {
750fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
751289bc588SBarry Smith       for (i=0; i<m; i++) {
7523bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
75355a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
754289bc588SBarry Smith       }
755289bc588SBarry Smith     }
756fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
757289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
7583bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
75955a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
760289bc588SBarry Smith       }
761289bc588SBarry Smith     }
762289bc588SBarry Smith   }
763d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
7641ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
7653a40ed3dSBarry Smith   PetscFunctionReturn(0);
766289bc588SBarry Smith }
767289bc588SBarry Smith 
768289bc588SBarry Smith /* -----------------------------------------------------------------*/
769ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
770289bc588SBarry Smith {
771c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
772d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
773d9ca1df4SBarry Smith   PetscScalar       *y;
774dfbe8321SBarry Smith   PetscErrorCode    ierr;
7750805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
776ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
7773a40ed3dSBarry Smith 
7783a40ed3dSBarry Smith   PetscFunctionBegin;
779c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
780c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
781d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
7822bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
7835ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
7845ac36cfcSBarry Smith     PetscBLASInt i;
7855ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
7865ac36cfcSBarry Smith   } else {
7878b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
7885ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
7895ac36cfcSBarry Smith   }
790d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
7912bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
7923a40ed3dSBarry Smith   PetscFunctionReturn(0);
793289bc588SBarry Smith }
794800995b7SMatthew Knepley 
795ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
796289bc588SBarry Smith {
797c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
798d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
799dfbe8321SBarry Smith   PetscErrorCode    ierr;
8000805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
801d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
8023a40ed3dSBarry Smith 
8033a40ed3dSBarry Smith   PetscFunctionBegin;
804c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
805c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
806d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8072bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
8085ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8095ac36cfcSBarry Smith     PetscBLASInt i;
8105ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
8115ac36cfcSBarry Smith   } else {
8128b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
8135ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
8145ac36cfcSBarry Smith   }
815d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8162bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
8173a40ed3dSBarry Smith   PetscFunctionReturn(0);
818289bc588SBarry Smith }
8196ee01492SSatish Balay 
820ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
821289bc588SBarry Smith {
822c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
823d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
824d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
825dfbe8321SBarry Smith   PetscErrorCode    ierr;
8260805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
8273a40ed3dSBarry Smith 
8283a40ed3dSBarry Smith   PetscFunctionBegin;
829c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
830c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
831d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
832600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
833d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8341ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8358b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
836d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8371ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
838dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8393a40ed3dSBarry Smith   PetscFunctionReturn(0);
840289bc588SBarry Smith }
8416ee01492SSatish Balay 
842ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
843289bc588SBarry Smith {
844c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
845d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
846d9ca1df4SBarry Smith   PetscScalar       *y;
847dfbe8321SBarry Smith   PetscErrorCode    ierr;
8480805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
84987828ca2SBarry Smith   PetscScalar       _DOne=1.0;
8503a40ed3dSBarry Smith 
8513a40ed3dSBarry Smith   PetscFunctionBegin;
852c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
853c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
854d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
855600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
856d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8571ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8588b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
859d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8601ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
861dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8623a40ed3dSBarry Smith   PetscFunctionReturn(0);
863289bc588SBarry Smith }
864289bc588SBarry Smith 
865289bc588SBarry Smith /* -----------------------------------------------------------------*/
866e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
867289bc588SBarry Smith {
868c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
8696849ba73SBarry Smith   PetscErrorCode ierr;
87013f74950SBarry Smith   PetscInt       i;
87167e560aaSBarry Smith 
8723a40ed3dSBarry Smith   PetscFunctionBegin;
873d0f46423SBarry Smith   *ncols = A->cmap->n;
874289bc588SBarry Smith   if (cols) {
875854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
876d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
877289bc588SBarry Smith   }
878289bc588SBarry Smith   if (vals) {
879ca15aa20SStefano Zampini     const PetscScalar *v;
880ca15aa20SStefano Zampini 
881ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
882854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
883ca15aa20SStefano Zampini     v   += row;
884d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
885ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
886289bc588SBarry Smith   }
8873a40ed3dSBarry Smith   PetscFunctionReturn(0);
888289bc588SBarry Smith }
8896ee01492SSatish Balay 
890e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
891289bc588SBarry Smith {
892dfbe8321SBarry Smith   PetscErrorCode ierr;
8936e111a19SKarl Rupp 
894606d414cSSatish Balay   PetscFunctionBegin;
895606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
896606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
8973a40ed3dSBarry Smith   PetscFunctionReturn(0);
898289bc588SBarry Smith }
899289bc588SBarry Smith /* ----------------------------------------------------------------*/
900e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
901289bc588SBarry Smith {
902c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
903ca15aa20SStefano Zampini   PetscScalar      *av;
90413f74950SBarry Smith   PetscInt         i,j,idx=0;
905ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
906c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
907ca15aa20SStefano Zampini #endif
908ca15aa20SStefano Zampini   PetscErrorCode   ierr;
909d6dfbf8fSBarry Smith 
9103a40ed3dSBarry Smith   PetscFunctionBegin;
911ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&av);CHKERRQ(ierr);
912289bc588SBarry Smith   if (!mat->roworiented) {
913dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
914289bc588SBarry Smith       for (j=0; j<n; j++) {
915cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
9162515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
917e32f2f54SBarry 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);
91858804f6dSBarry Smith #endif
919289bc588SBarry Smith         for (i=0; i<m; i++) {
920cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
9212515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
922e32f2f54SBarry 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);
92358804f6dSBarry Smith #endif
924ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
925289bc588SBarry Smith         }
926289bc588SBarry Smith       }
9273a40ed3dSBarry Smith     } else {
928289bc588SBarry Smith       for (j=0; j<n; j++) {
929cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
9302515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
931e32f2f54SBarry 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);
93258804f6dSBarry Smith #endif
933289bc588SBarry Smith         for (i=0; i<m; i++) {
934cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
9352515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
936e32f2f54SBarry 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);
93758804f6dSBarry Smith #endif
938ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
939289bc588SBarry Smith         }
940289bc588SBarry Smith       }
941289bc588SBarry Smith     }
9423a40ed3dSBarry Smith   } else {
943dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
944e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
945cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
9462515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
947e32f2f54SBarry Smith         if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
94858804f6dSBarry Smith #endif
949e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
950cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
9512515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
952e32f2f54SBarry 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);
95358804f6dSBarry Smith #endif
954ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
955e8d4e0b9SBarry Smith         }
956e8d4e0b9SBarry Smith       }
9573a40ed3dSBarry Smith     } else {
958289bc588SBarry Smith       for (i=0; i<m; i++) {
959cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
9602515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
961e32f2f54SBarry Smith         if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
96258804f6dSBarry Smith #endif
963289bc588SBarry Smith         for (j=0; j<n; j++) {
964cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
9652515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
966e32f2f54SBarry 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);
96758804f6dSBarry Smith #endif
968ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
969289bc588SBarry Smith         }
970289bc588SBarry Smith       }
971289bc588SBarry Smith     }
972e8d4e0b9SBarry Smith   }
973ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
974ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
975c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
976c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
977ca15aa20SStefano Zampini #endif
978ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&av);CHKERRQ(ierr);
979ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
980c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
981ca15aa20SStefano Zampini #endif
9823a40ed3dSBarry Smith   PetscFunctionReturn(0);
983289bc588SBarry Smith }
984e8d4e0b9SBarry Smith 
985e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
986ae80bb75SLois Curfman McInnes {
987ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
988ca15aa20SStefano Zampini   const PetscScalar *vv;
98913f74950SBarry Smith   PetscInt          i,j;
990ca15aa20SStefano Zampini   PetscErrorCode    ierr;
991ae80bb75SLois Curfman McInnes 
9923a40ed3dSBarry Smith   PetscFunctionBegin;
993ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
994ae80bb75SLois Curfman McInnes   /* row-oriented output */
995ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
99697e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
997e32f2f54SBarry 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);
998ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
9996f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1000e32f2f54SBarry 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);
1001ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1002ae80bb75SLois Curfman McInnes     }
1003ae80bb75SLois Curfman McInnes   }
1004ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
10053a40ed3dSBarry Smith   PetscFunctionReturn(0);
1006ae80bb75SLois Curfman McInnes }
1007ae80bb75SLois Curfman McInnes 
1008289bc588SBarry Smith /* -----------------------------------------------------------------*/
1009289bc588SBarry Smith 
10108491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1011aabbc4fbSShri Abhyankar {
1012aabbc4fbSShri Abhyankar   PetscErrorCode    ierr;
10138491ab44SLisandro Dalcin   PetscBool         skipHeader;
10148491ab44SLisandro Dalcin   PetscViewerFormat format;
10158491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
10168491ab44SLisandro Dalcin   const PetscScalar *v;
10178491ab44SLisandro Dalcin   PetscScalar       *vwork;
1018aabbc4fbSShri Abhyankar 
1019aabbc4fbSShri Abhyankar   PetscFunctionBegin;
10208491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
10218491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
10228491ab44SLisandro Dalcin   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
10238491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1024aabbc4fbSShri Abhyankar 
10258491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
10268491ab44SLisandro Dalcin 
10278491ab44SLisandro Dalcin   /* write matrix header */
10288491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
10298491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
10308491ab44SLisandro Dalcin   if (!skipHeader) {ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);}
10318491ab44SLisandro Dalcin 
10328491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
10338491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
10348491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
10358491ab44SLisandro Dalcin     /* store row lengths for each row */
10368491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
10378491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
10388491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
10398491ab44SLisandro Dalcin     /* store column indices (zero start index) */
10408491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
10418491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
10428491ab44SLisandro Dalcin         iwork[k] = j;
10438491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
10448491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
10458491ab44SLisandro Dalcin   }
10468491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
10478491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
10488491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
10498491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
10508491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
10518491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
10528491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
10538491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
10548491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
10558491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
10568491ab44SLisandro Dalcin   PetscFunctionReturn(0);
10578491ab44SLisandro Dalcin }
10588491ab44SLisandro Dalcin 
10598491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
10608491ab44SLisandro Dalcin {
10618491ab44SLisandro Dalcin   PetscErrorCode ierr;
10628491ab44SLisandro Dalcin   PetscBool      skipHeader;
10638491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
10648491ab44SLisandro Dalcin   PetscInt       rows,cols;
10658491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
10668491ab44SLisandro Dalcin 
10678491ab44SLisandro Dalcin   PetscFunctionBegin;
10688491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
10698491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
10708491ab44SLisandro Dalcin 
10718491ab44SLisandro Dalcin   if (!skipHeader) {
10728491ab44SLisandro Dalcin     ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
10738491ab44SLisandro Dalcin     if (header[0] != MAT_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
10748491ab44SLisandro Dalcin     M = header[1]; N = header[2];
10758491ab44SLisandro Dalcin     if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M);
10768491ab44SLisandro Dalcin     if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N);
10778491ab44SLisandro Dalcin     nz = header[3];
10788491ab44SLisandro Dalcin     if (nz != MATRIX_BINARY_FORMAT_DENSE && nz < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %D in file",nz);
1079aabbc4fbSShri Abhyankar   } else {
10808491ab44SLisandro Dalcin     ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
10818491ab44SLisandro 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");
10828491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1083e6324fbbSBarry Smith   }
1084aabbc4fbSShri Abhyankar 
10858491ab44SLisandro Dalcin   /* setup global sizes if not set */
10868491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
10878491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
10888491ab44SLisandro Dalcin   ierr = MatSetUp(mat);CHKERRQ(ierr);
10898491ab44SLisandro Dalcin   /* check if global sizes are correct */
10908491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
10918491ab44SLisandro 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);
1092aabbc4fbSShri Abhyankar 
10938491ab44SLisandro Dalcin   ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
10948491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
10958491ab44SLisandro Dalcin   ierr = MatDenseGetArray(mat,&v);CHKERRQ(ierr);
10968491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
10978491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
10988491ab44SLisandro Dalcin     PetscInt nnz = m*N;
10998491ab44SLisandro Dalcin     /* read in matrix values */
11008491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&vwork);CHKERRQ(ierr);
11018491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
11028491ab44SLisandro Dalcin     /* store values in column major order */
11038491ab44SLisandro Dalcin     for (j=0; j<N; j++)
11048491ab44SLisandro Dalcin       for (i=0; i<m; i++)
11058491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
11068491ab44SLisandro Dalcin     ierr = PetscFree(vwork);CHKERRQ(ierr);
11078491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
11088491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
11098491ab44SLisandro Dalcin     /* read in row lengths */
11108491ab44SLisandro Dalcin     ierr = PetscMalloc1(m,&rlens);CHKERRQ(ierr);
11118491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
11128491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
11138491ab44SLisandro Dalcin     /* read in column indices and values */
11148491ab44SLisandro Dalcin     ierr = PetscMalloc2(nnz,&icols,nnz,&vwork);CHKERRQ(ierr);
11158491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
11168491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
11178491ab44SLisandro Dalcin     /* store values in column major order */
11188491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
11198491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
11208491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
11218491ab44SLisandro Dalcin     ierr = PetscFree(rlens);CHKERRQ(ierr);
11228491ab44SLisandro Dalcin     ierr = PetscFree2(icols,vwork);CHKERRQ(ierr);
1123aabbc4fbSShri Abhyankar   }
11248491ab44SLisandro Dalcin   ierr = MatDenseRestoreArray(mat,&v);CHKERRQ(ierr);
11258491ab44SLisandro Dalcin   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
11268491ab44SLisandro Dalcin   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1127aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1128aabbc4fbSShri Abhyankar }
1129aabbc4fbSShri Abhyankar 
1130eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1131eb91f321SVaclav Hapla {
1132eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1133eb91f321SVaclav Hapla   PetscErrorCode ierr;
1134eb91f321SVaclav Hapla 
1135eb91f321SVaclav Hapla   PetscFunctionBegin;
1136eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1137eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1138eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
1139eb91f321SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1140eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1141eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1142eb91f321SVaclav Hapla   if (isbinary) {
11438491ab44SLisandro Dalcin     ierr = MatLoad_Dense_Binary(newMat,viewer);CHKERRQ(ierr);
1144eb91f321SVaclav Hapla   } else if (ishdf5) {
1145eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
1146eb91f321SVaclav Hapla     ierr = MatLoad_Dense_HDF5(newMat,viewer);CHKERRQ(ierr);
1147eb91f321SVaclav Hapla #else
1148eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1149eb91f321SVaclav Hapla #endif
1150eb91f321SVaclav Hapla   } else {
1151eb91f321SVaclav 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);
1152eb91f321SVaclav Hapla   }
1153eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1154eb91f321SVaclav Hapla }
1155eb91f321SVaclav Hapla 
11566849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1157289bc588SBarry Smith {
1158932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1159dfbe8321SBarry Smith   PetscErrorCode    ierr;
116013f74950SBarry Smith   PetscInt          i,j;
11612dcb1b2aSMatthew Knepley   const char        *name;
1162ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1163f3ef73ceSBarry Smith   PetscViewerFormat format;
11645f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1165ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
11665f481a85SSatish Balay #endif
1167932b0c3eSLois Curfman McInnes 
11683a40ed3dSBarry Smith   PetscFunctionBegin;
1169ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1170b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1171456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
11723a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1173fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1174d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1175d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1176ca15aa20SStefano Zampini       v    = av + i;
117777431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1178d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1179aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1180329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
118157622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1182329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
118357622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
11846831982aSBarry Smith         }
118580cd9d93SLois Curfman McInnes #else
11866831982aSBarry Smith         if (*v) {
118757622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
11886831982aSBarry Smith         }
118980cd9d93SLois Curfman McInnes #endif
11901b807ce4Svictorle         v += a->lda;
119180cd9d93SLois Curfman McInnes       }
1192b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
119380cd9d93SLois Curfman McInnes     }
1194d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
11953a40ed3dSBarry Smith   } else {
1196d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1197aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
119847989497SBarry Smith     /* determine if matrix has all real values */
1199ca15aa20SStefano Zampini     v = av;
1200d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1201ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
120247989497SBarry Smith     }
120347989497SBarry Smith #endif
1204fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
12053a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1206d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1207d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1208fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1209ffac6cdbSBarry Smith     }
1210ffac6cdbSBarry Smith 
1211d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1212ca15aa20SStefano Zampini       v = av + i;
1213d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1214aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
121547989497SBarry Smith         if (allreal) {
1216c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
121747989497SBarry Smith         } else {
1218c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
121947989497SBarry Smith         }
1220289bc588SBarry Smith #else
1221c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1222289bc588SBarry Smith #endif
12231b807ce4Svictorle         v += a->lda;
1224289bc588SBarry Smith       }
1225b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1226289bc588SBarry Smith     }
1227fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1228b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1229ffac6cdbSBarry Smith     }
1230d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1231da3a660dSBarry Smith   }
1232ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1233b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
12343a40ed3dSBarry Smith   PetscFunctionReturn(0);
1235289bc588SBarry Smith }
1236289bc588SBarry Smith 
12378491ab44SLisandro Dalcin static PetscErrorCode MatView_SeqDense_Binary(Mat mat,PetscViewer viewer)
1238932b0c3eSLois Curfman McInnes {
12396849ba73SBarry Smith   PetscErrorCode    ierr;
1240f4403165SShri Abhyankar   PetscViewerFormat format;
12418491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
12428491ab44SLisandro Dalcin   const PetscScalar *v;
12438491ab44SLisandro Dalcin   PetscScalar       *vwork;
1244932b0c3eSLois Curfman McInnes 
12453a40ed3dSBarry Smith   PetscFunctionBegin;
12468491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
12478491ab44SLisandro Dalcin 
1248f4403165SShri Abhyankar   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
12498491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
12502205254eSKarl Rupp 
12518491ab44SLisandro Dalcin   /* write matrix header */
12528491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
12538491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
12548491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);
12552205254eSKarl Rupp 
12568491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
12578491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
12588491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
12598491ab44SLisandro Dalcin     /* store row lengths for each row */
12608491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
12618491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
12628491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWrite(viewer,iwork,m,PETSC_INT);CHKERRQ(ierr);
1263932b0c3eSLois Curfman McInnes     /* store column indices (zero start index) */
12648491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
12658491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
12668491ab44SLisandro Dalcin         iwork[k] = j;
12678491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWrite(viewer,iwork,nnz,PETSC_INT);CHKERRQ(ierr);
12688491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
1269932b0c3eSLois Curfman McInnes   }
12708491ab44SLisandro Dalcin   /* store the matrix values as a dense matrix in row major order */
12718491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
12728491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
12738491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
12748491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
12758491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
12768491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
12778491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
12788491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWrite(viewer,vwork,m*N,PETSC_SCALAR);CHKERRQ(ierr);
12798491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
12803a40ed3dSBarry Smith   PetscFunctionReturn(0);
1281932b0c3eSLois Curfman McInnes }
1282932b0c3eSLois Curfman McInnes 
12839804daf3SBarry Smith #include <petscdraw.h>
1284e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1285f1af5d2fSBarry Smith {
1286f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
12876849ba73SBarry Smith   PetscErrorCode    ierr;
1288383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1289383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1290ca15aa20SStefano Zampini   const PetscScalar *v;
1291b0a32e0cSBarry Smith   PetscViewer       viewer;
1292b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1293f3ef73ceSBarry Smith   PetscViewerFormat format;
1294f1af5d2fSBarry Smith 
1295f1af5d2fSBarry Smith   PetscFunctionBegin;
1296f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1297b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1298b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1299f1af5d2fSBarry Smith 
1300f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1301ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1302fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1303383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1304f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1305f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1306383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1307f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1308f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1309f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1310ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1311ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1312ca15aa20SStefano Zampini         else continue;
1313b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1314f1af5d2fSBarry Smith       }
1315f1af5d2fSBarry Smith     }
1316383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1317f1af5d2fSBarry Smith   } else {
1318f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1319f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1320b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1321b05fc000SLisandro Dalcin     PetscDraw popup;
1322b05fc000SLisandro Dalcin 
1323f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1324f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1325f1af5d2fSBarry Smith     }
1326383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1327b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
132845f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1329383922c3SLisandro Dalcin 
1330383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1331f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1332f1af5d2fSBarry Smith       x_l = j;
1333f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1334f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1335f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1336f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1337b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1338b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1339f1af5d2fSBarry Smith       }
1340f1af5d2fSBarry Smith     }
1341383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1342f1af5d2fSBarry Smith   }
1343ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1344f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1345f1af5d2fSBarry Smith }
1346f1af5d2fSBarry Smith 
1347e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1348f1af5d2fSBarry Smith {
1349b0a32e0cSBarry Smith   PetscDraw      draw;
1350ace3abfcSBarry Smith   PetscBool      isnull;
1351329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1352dfbe8321SBarry Smith   PetscErrorCode ierr;
1353f1af5d2fSBarry Smith 
1354f1af5d2fSBarry Smith   PetscFunctionBegin;
1355b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1356b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1357abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1358f1af5d2fSBarry Smith 
1359d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1360f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1361b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1362832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1363b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
13640298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1365832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1366f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1367f1af5d2fSBarry Smith }
1368f1af5d2fSBarry Smith 
1369dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1370932b0c3eSLois Curfman McInnes {
1371dfbe8321SBarry Smith   PetscErrorCode ierr;
1372ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1373932b0c3eSLois Curfman McInnes 
13743a40ed3dSBarry Smith   PetscFunctionBegin;
1375251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1376251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1377251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
13780f5bd95cSBarry Smith 
1379c45a1595SBarry Smith   if (iascii) {
1380c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
13810f5bd95cSBarry Smith   } else if (isbinary) {
13823a40ed3dSBarry Smith     ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr);
1383f1af5d2fSBarry Smith   } else if (isdraw) {
1384f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1385932b0c3eSLois Curfman McInnes   }
13863a40ed3dSBarry Smith   PetscFunctionReturn(0);
1387932b0c3eSLois Curfman McInnes }
1388289bc588SBarry Smith 
1389d3042a70SBarry Smith static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar array[])
1390d3042a70SBarry Smith {
1391d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1392d3042a70SBarry Smith 
1393d3042a70SBarry Smith   PetscFunctionBegin;
1394d3042a70SBarry Smith   a->unplacedarray       = a->v;
1395d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1396d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1397ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1398c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1399ca15aa20SStefano Zampini #endif
1400d3042a70SBarry Smith   PetscFunctionReturn(0);
1401d3042a70SBarry Smith }
1402d3042a70SBarry Smith 
1403d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1404d3042a70SBarry Smith {
1405d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1406d3042a70SBarry Smith 
1407d3042a70SBarry Smith   PetscFunctionBegin;
1408d3042a70SBarry Smith   a->v             = a->unplacedarray;
1409d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1410d3042a70SBarry Smith   a->unplacedarray = NULL;
1411ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1412c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1413ca15aa20SStefano Zampini #endif
1414d3042a70SBarry Smith   PetscFunctionReturn(0);
1415d3042a70SBarry Smith }
1416d3042a70SBarry Smith 
1417ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1418289bc588SBarry Smith {
1419ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1420dfbe8321SBarry Smith   PetscErrorCode ierr;
142190f02eecSBarry Smith 
14223a40ed3dSBarry Smith   PetscFunctionBegin;
1423aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1424d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1425a5a9c739SBarry Smith #endif
142605b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1427a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1428abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
14296857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1430bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1431dbd8c25aSHong Zhang 
1432dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
143349a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1434bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
143552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
1436d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1437d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
143852c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL);CHKERRQ(ierr);
143952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL);CHKERRQ(ierr);
14408baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
14418baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
14428baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
14438baccfbdSHong Zhang #endif
14442bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
14452bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL);CHKERRQ(ierr);
14464222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL);CHKERRQ(ierr);
14474222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL);CHKERRQ(ierr);
14484222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaijcusparse_seqdense_C",NULL);CHKERRQ(ierr);
14492bf066beSStefano Zampini #endif
1450bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
14514222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14524222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL);CHKERRQ(ierr);
1453bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1454bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14554222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1456a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1457a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
14584222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
1459c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
1460c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
146152c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
146252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
146352c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
146452c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
146552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
146652c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
146752c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_nest_seqdense_C",NULL);CHKERRQ(ierr);
146852c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_nest_seqdense_C",NULL);CHKERRQ(ierr);
146952c5f739Sprj- 
14703bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14713bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
147252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
147352c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
147452c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
147552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
147652c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
147752c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
147886aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
147986aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
14803a40ed3dSBarry Smith   PetscFunctionReturn(0);
1481289bc588SBarry Smith }
1482289bc588SBarry Smith 
1483e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1484289bc588SBarry Smith {
1485c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
14866849ba73SBarry Smith   PetscErrorCode ierr;
148713f74950SBarry Smith   PetscInt       k,j,m,n,M;
148887828ca2SBarry Smith   PetscScalar    *v,tmp;
148948b35521SBarry Smith 
14903a40ed3dSBarry Smith   PetscFunctionBegin;
1491ca15aa20SStefano Zampini   m = A->rmap->n; M = mat->lda; n = A->cmap->n;
14922847e3fdSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX && m == n) { /* in place transpose */
1493ca15aa20SStefano Zampini     ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1494d3e5ee88SLois Curfman McInnes     for (j=0; j<m; j++) {
1495289bc588SBarry Smith       for (k=0; k<j; k++) {
14961b807ce4Svictorle         tmp        = v[j + k*M];
14971b807ce4Svictorle         v[j + k*M] = v[k + j*M];
14981b807ce4Svictorle         v[k + j*M] = tmp;
1499289bc588SBarry Smith       }
1500289bc588SBarry Smith     }
1501ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
15023a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1503d3e5ee88SLois Curfman McInnes     Mat          tmat;
1504ec8511deSBarry Smith     Mat_SeqDense *tmatd;
150587828ca2SBarry Smith     PetscScalar  *v2;
1506af36a384SStefano Zampini     PetscInt     M2;
1507ea709b57SSatish Balay 
15082847e3fdSStefano Zampini     if (reuse != MAT_REUSE_MATRIX) {
1509ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1510d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
15117adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
15120298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1513ca15aa20SStefano Zampini     } else tmat = *matout;
1514ca15aa20SStefano Zampini 
1515ca15aa20SStefano Zampini     ierr  = MatDenseGetArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
1516ca15aa20SStefano Zampini     ierr  = MatDenseGetArray(tmat,&v2);CHKERRQ(ierr);
1517ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1518ca15aa20SStefano Zampini     M2    = tmatd->lda;
1519d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1520af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1521d3e5ee88SLois Curfman McInnes     }
1522ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(tmat,&v2);CHKERRQ(ierr);
1523ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
15246d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15256d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15262847e3fdSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) *matout = tmat;
15272847e3fdSStefano Zampini     else {
15282847e3fdSStefano Zampini       ierr = MatHeaderMerge(A,&tmat);CHKERRQ(ierr);
15292847e3fdSStefano Zampini     }
153048b35521SBarry Smith   }
15313a40ed3dSBarry Smith   PetscFunctionReturn(0);
1532289bc588SBarry Smith }
1533289bc588SBarry Smith 
1534e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1535289bc588SBarry Smith {
1536c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1537c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1538ca15aa20SStefano Zampini   PetscInt          i;
1539ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
1540ca15aa20SStefano Zampini   PetscErrorCode    ierr;
15419ea5d5aeSSatish Balay 
15423a40ed3dSBarry Smith   PetscFunctionBegin;
1543d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1544d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1545ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A1,&v1);CHKERRQ(ierr);
1546ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A2,&v2);CHKERRQ(ierr);
1547ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
1548ca15aa20SStefano Zampini     ierr = PetscArraycmp(v1,v2,A1->rmap->n,flg);CHKERRQ(ierr);
1549ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1550ca15aa20SStefano Zampini     v1 += mat1->lda;
1551ca15aa20SStefano Zampini     v2 += mat2->lda;
15521b807ce4Svictorle   }
1553ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A1,&v1);CHKERRQ(ierr);
1554ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A2,&v2);CHKERRQ(ierr);
155577c4ece6SBarry Smith   *flg = PETSC_TRUE;
15563a40ed3dSBarry Smith   PetscFunctionReturn(0);
1557289bc588SBarry Smith }
1558289bc588SBarry Smith 
1559e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1560289bc588SBarry Smith {
1561c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
156213f74950SBarry Smith   PetscInt          i,n,len;
1563ca15aa20SStefano Zampini   PetscScalar       *x;
1564ca15aa20SStefano Zampini   const PetscScalar *vv;
1565ca15aa20SStefano Zampini   PetscErrorCode    ierr;
156644cd7ae7SLois Curfman McInnes 
15673a40ed3dSBarry Smith   PetscFunctionBegin;
15687a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
15691ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1570d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1571ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1572e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
157344cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1574ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1575289bc588SBarry Smith   }
1576ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
15771ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
15783a40ed3dSBarry Smith   PetscFunctionReturn(0);
1579289bc588SBarry Smith }
1580289bc588SBarry Smith 
1581e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1582289bc588SBarry Smith {
1583c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1584f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1585ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1586dfbe8321SBarry Smith   PetscErrorCode    ierr;
1587d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
158855659b69SBarry Smith 
15893a40ed3dSBarry Smith   PetscFunctionBegin;
1590ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&vv);CHKERRQ(ierr);
159128988994SBarry Smith   if (ll) {
15927a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1593f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1594e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1595da3a660dSBarry Smith     for (i=0; i<m; i++) {
1596da3a660dSBarry Smith       x = l[i];
1597ca15aa20SStefano Zampini       v = vv + i;
1598b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1599da3a660dSBarry Smith     }
1600f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1601eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1602da3a660dSBarry Smith   }
160328988994SBarry Smith   if (rr) {
16047a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1605f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1606e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1607da3a660dSBarry Smith     for (i=0; i<n; i++) {
1608da3a660dSBarry Smith       x = r[i];
1609ca15aa20SStefano Zampini       v = vv + i*mat->lda;
16102205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1611da3a660dSBarry Smith     }
1612f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1613eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1614da3a660dSBarry Smith   }
1615ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&vv);CHKERRQ(ierr);
16163a40ed3dSBarry Smith   PetscFunctionReturn(0);
1617289bc588SBarry Smith }
1618289bc588SBarry Smith 
1619ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1620289bc588SBarry Smith {
1621c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1622ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1623329f5518SBarry Smith   PetscReal         sum  = 0.0;
1624d0f46423SBarry Smith   PetscInt          lda  =mat->lda,m=A->rmap->n,i,j;
1625efee365bSSatish Balay   PetscErrorCode    ierr;
162655659b69SBarry Smith 
16273a40ed3dSBarry Smith   PetscFunctionBegin;
1628ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
1629ca15aa20SStefano Zampini   v    = vv;
1630289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1631a5ce6ee0Svictorle     if (lda>m) {
1632d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1633ca15aa20SStefano Zampini         v = vv+j*lda;
1634a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1635a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1636a5ce6ee0Svictorle         }
1637a5ce6ee0Svictorle       }
1638a5ce6ee0Svictorle     } else {
1639570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1640570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1641570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1642570b7f6dSBarry Smith     }
1643570b7f6dSBarry Smith #else
1644d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1645329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1646289bc588SBarry Smith       }
1647a5ce6ee0Svictorle     }
16488f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1649570b7f6dSBarry Smith #endif
1650dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16513a40ed3dSBarry Smith   } else if (type == NORM_1) {
1652064f8208SBarry Smith     *nrm = 0.0;
1653d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1654ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
1655289bc588SBarry Smith       sum = 0.0;
1656d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
165733a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1658289bc588SBarry Smith       }
1659064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1660289bc588SBarry Smith     }
1661eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16623a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1663064f8208SBarry Smith     *nrm = 0.0;
1664d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1665ca15aa20SStefano Zampini       v   = vv + j;
1666289bc588SBarry Smith       sum = 0.0;
1667d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
16681b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1669289bc588SBarry Smith       }
1670064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1671289bc588SBarry Smith     }
1672eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1673e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
1674ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
16753a40ed3dSBarry Smith   PetscFunctionReturn(0);
1676289bc588SBarry Smith }
1677289bc588SBarry Smith 
1678e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1679289bc588SBarry Smith {
1680c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
168163ba0a88SBarry Smith   PetscErrorCode ierr;
168267e560aaSBarry Smith 
16833a40ed3dSBarry Smith   PetscFunctionBegin;
1684b5a2b587SKris Buschelman   switch (op) {
1685b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
16864e0d8c25SBarry Smith     aij->roworiented = flg;
1687b5a2b587SKris Buschelman     break;
1688512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1689b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
16903971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
16914e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
169213fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1693b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1694b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
16950f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
16965021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
1697071fcb05SBarry Smith   case MAT_SORTED_FULL:
16985021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
16995021d80fSJed Brown     break;
17005021d80fSJed Brown   case MAT_SPD:
170177e54ba9SKris Buschelman   case MAT_SYMMETRIC:
170277e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
17039a4540c5SBarry Smith   case MAT_HERMITIAN:
17049a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
17055021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
170677e54ba9SKris Buschelman     break;
1707b5a2b587SKris Buschelman   default:
1708e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
17093a40ed3dSBarry Smith   }
17103a40ed3dSBarry Smith   PetscFunctionReturn(0);
1711289bc588SBarry Smith }
1712289bc588SBarry Smith 
1713e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
17146f0a148fSBarry Smith {
1715ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
17166849ba73SBarry Smith   PetscErrorCode ierr;
1717d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
1718ca15aa20SStefano Zampini   PetscScalar    *v;
17193a40ed3dSBarry Smith 
17203a40ed3dSBarry Smith   PetscFunctionBegin;
1721ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1722a5ce6ee0Svictorle   if (lda>m) {
1723d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1724ca15aa20SStefano Zampini       ierr = PetscArrayzero(v+j*lda,m);CHKERRQ(ierr);
1725a5ce6ee0Svictorle     }
1726a5ce6ee0Svictorle   } else {
1727ca15aa20SStefano Zampini     ierr = PetscArrayzero(v,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
1728a5ce6ee0Svictorle   }
1729ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17303a40ed3dSBarry Smith   PetscFunctionReturn(0);
17316f0a148fSBarry Smith }
17326f0a148fSBarry Smith 
1733e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
17346f0a148fSBarry Smith {
173597b48c8fSBarry Smith   PetscErrorCode    ierr;
1736ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1737b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
1738ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
173997b48c8fSBarry Smith   const PetscScalar *xx;
174055659b69SBarry Smith 
17413a40ed3dSBarry Smith   PetscFunctionBegin;
1742b9679d65SBarry Smith #if defined(PETSC_USE_DEBUG)
1743b9679d65SBarry Smith   for (i=0; i<N; i++) {
1744b9679d65SBarry Smith     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1745b9679d65SBarry 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);
1746b9679d65SBarry Smith   }
1747b9679d65SBarry Smith #endif
1748ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1749b9679d65SBarry Smith 
175097b48c8fSBarry Smith   /* fix right hand side if needed */
175197b48c8fSBarry Smith   if (x && b) {
175297b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
175397b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
17542205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
175597b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
175697b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
175797b48c8fSBarry Smith   }
175897b48c8fSBarry Smith 
1759ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
17606f0a148fSBarry Smith   for (i=0; i<N; i++) {
1761ca15aa20SStefano Zampini     slot = v + rows[i];
1762b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
17636f0a148fSBarry Smith   }
1764f4df32b1SMatthew Knepley   if (diag != 0.0) {
1765b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
17666f0a148fSBarry Smith     for (i=0; i<N; i++) {
1767ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1768f4df32b1SMatthew Knepley       *slot = diag;
17696f0a148fSBarry Smith     }
17706f0a148fSBarry Smith   }
1771ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17723a40ed3dSBarry Smith   PetscFunctionReturn(0);
17736f0a148fSBarry Smith }
1774557bce09SLois Curfman McInnes 
177549a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
177649a6ff4bSBarry Smith {
177749a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
177849a6ff4bSBarry Smith 
177949a6ff4bSBarry Smith   PetscFunctionBegin;
178049a6ff4bSBarry Smith   *lda = mat->lda;
178149a6ff4bSBarry Smith   PetscFunctionReturn(0);
178249a6ff4bSBarry Smith }
178349a6ff4bSBarry Smith 
1784ca15aa20SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar *array[])
178564e87e97SBarry Smith {
1786c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
17873a40ed3dSBarry Smith 
17883a40ed3dSBarry Smith   PetscFunctionBegin;
178964e87e97SBarry Smith   *array = mat->v;
17903a40ed3dSBarry Smith   PetscFunctionReturn(0);
179164e87e97SBarry Smith }
17920754003eSLois Curfman McInnes 
1793ca15aa20SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar *array[])
1794ff14e315SSatish Balay {
17953a40ed3dSBarry Smith   PetscFunctionBegin;
17963a40ed3dSBarry Smith   PetscFunctionReturn(0);
1797ff14e315SSatish Balay }
17980754003eSLois Curfman McInnes 
1799dec5eb66SMatthew G Knepley /*@C
180049a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
180149a6ff4bSBarry Smith 
180249a6ff4bSBarry Smith    Logically Collective on Mat
180349a6ff4bSBarry Smith 
180449a6ff4bSBarry Smith    Input Parameter:
180549a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
180649a6ff4bSBarry Smith 
180749a6ff4bSBarry Smith    Output Parameter:
180849a6ff4bSBarry Smith .   lda - the leading dimension
180949a6ff4bSBarry Smith 
181049a6ff4bSBarry Smith    Level: intermediate
181149a6ff4bSBarry Smith 
181249a6ff4bSBarry Smith .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatSeqDenseSetLDA()
181349a6ff4bSBarry Smith @*/
181449a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
181549a6ff4bSBarry Smith {
181649a6ff4bSBarry Smith   PetscErrorCode ierr;
181749a6ff4bSBarry Smith 
181849a6ff4bSBarry Smith   PetscFunctionBegin;
181949a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
182049a6ff4bSBarry Smith   PetscFunctionReturn(0);
182149a6ff4bSBarry Smith }
182249a6ff4bSBarry Smith 
182349a6ff4bSBarry Smith /*@C
18248c778c55SBarry Smith    MatDenseGetArray - gives access to the array where the data for a SeqDense matrix is stored
182573a71a0fSBarry Smith 
18268572280aSBarry Smith    Logically Collective on Mat
182773a71a0fSBarry Smith 
182873a71a0fSBarry Smith    Input Parameter:
1829579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
183073a71a0fSBarry Smith 
183173a71a0fSBarry Smith    Output Parameter:
183273a71a0fSBarry Smith .   array - pointer to the data
183373a71a0fSBarry Smith 
183473a71a0fSBarry Smith    Level: intermediate
183573a71a0fSBarry Smith 
18368572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
183773a71a0fSBarry Smith @*/
18388c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
183973a71a0fSBarry Smith {
184073a71a0fSBarry Smith   PetscErrorCode ierr;
184173a71a0fSBarry Smith 
184273a71a0fSBarry Smith   PetscFunctionBegin;
18438c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
184473a71a0fSBarry Smith   PetscFunctionReturn(0);
184573a71a0fSBarry Smith }
184673a71a0fSBarry Smith 
1847dec5eb66SMatthew G Knepley /*@C
1848579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
184973a71a0fSBarry Smith 
18508572280aSBarry Smith    Logically Collective on Mat
18518572280aSBarry Smith 
18528572280aSBarry Smith    Input Parameters:
1853a2b725a8SWilliam Gropp +  mat - a MATSEQDENSE or MATMPIDENSE matrix
1854a2b725a8SWilliam Gropp -  array - pointer to the data
18558572280aSBarry Smith 
18568572280aSBarry Smith    Level: intermediate
18578572280aSBarry Smith 
18588572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
18598572280aSBarry Smith @*/
18608572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
18618572280aSBarry Smith {
18628572280aSBarry Smith   PetscErrorCode ierr;
18638572280aSBarry Smith 
18648572280aSBarry Smith   PetscFunctionBegin;
18658572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
18668572280aSBarry Smith   if (array) *array = NULL;
18678572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
18688572280aSBarry Smith   PetscFunctionReturn(0);
18698572280aSBarry Smith }
18708572280aSBarry Smith 
18718572280aSBarry Smith /*@C
18728572280aSBarry Smith    MatDenseGetArrayRead - gives access to the array where the data for a SeqDense matrix is stored
18738572280aSBarry Smith 
18748572280aSBarry Smith    Not Collective
18758572280aSBarry Smith 
18768572280aSBarry Smith    Input Parameter:
18778572280aSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
18788572280aSBarry Smith 
18798572280aSBarry Smith    Output Parameter:
18808572280aSBarry Smith .   array - pointer to the data
18818572280aSBarry Smith 
18828572280aSBarry Smith    Level: intermediate
18838572280aSBarry Smith 
18848572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArray(), MatDenseRestoreArrayRead()
18858572280aSBarry Smith @*/
18868572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
18878572280aSBarry Smith {
18888572280aSBarry Smith   PetscErrorCode ierr;
18898572280aSBarry Smith 
18908572280aSBarry Smith   PetscFunctionBegin;
18918572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
18928572280aSBarry Smith   PetscFunctionReturn(0);
18938572280aSBarry Smith }
18948572280aSBarry Smith 
18958572280aSBarry Smith /*@C
18968572280aSBarry Smith    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
18978572280aSBarry Smith 
189873a71a0fSBarry Smith    Not Collective
189973a71a0fSBarry Smith 
190073a71a0fSBarry Smith    Input Parameters:
1901a2b725a8SWilliam Gropp +  mat - a MATSEQDENSE or MATMPIDENSE matrix
1902a2b725a8SWilliam Gropp -  array - pointer to the data
190373a71a0fSBarry Smith 
190473a71a0fSBarry Smith    Level: intermediate
190573a71a0fSBarry Smith 
19068572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArray()
190773a71a0fSBarry Smith @*/
19088572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
190973a71a0fSBarry Smith {
191073a71a0fSBarry Smith   PetscErrorCode ierr;
191173a71a0fSBarry Smith 
191273a71a0fSBarry Smith   PetscFunctionBegin;
19138572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
19148572280aSBarry Smith   if (array) *array = NULL;
191573a71a0fSBarry Smith   PetscFunctionReturn(0);
191673a71a0fSBarry Smith }
191773a71a0fSBarry Smith 
19187dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
19190754003eSLois Curfman McInnes {
1920c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
19216849ba73SBarry Smith   PetscErrorCode ierr;
1922ca15aa20SStefano Zampini   PetscInt       i,j,nrows,ncols,blda;
19235d0c19d7SBarry Smith   const PetscInt *irow,*icol;
192487828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
19250754003eSLois Curfman McInnes   Mat            newmat;
19260754003eSLois Curfman McInnes 
19273a40ed3dSBarry Smith   PetscFunctionBegin;
192878b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
192978b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1930e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1931e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
19320754003eSLois Curfman McInnes 
1933182d2002SSatish Balay   /* Check submatrixcall */
1934182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
193513f74950SBarry Smith     PetscInt n_cols,n_rows;
1936182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
193721a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
1938f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
1939c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
194021a2c019SBarry Smith     }
1941182d2002SSatish Balay     newmat = *B;
1942182d2002SSatish Balay   } else {
19430754003eSLois Curfman McInnes     /* Create and fill new matrix */
1944ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
1945f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
19467adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
19470298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1948182d2002SSatish Balay   }
1949182d2002SSatish Balay 
1950182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1951ca15aa20SStefano Zampini   ierr = MatDenseGetArray(newmat,&bv);CHKERRQ(ierr);
1952ca15aa20SStefano Zampini   ierr = MatDenseGetLDA(newmat,&blda);CHKERRQ(ierr);
1953182d2002SSatish Balay   for (i=0; i<ncols; i++) {
19546de62eeeSBarry Smith     av = v + mat->lda*icol[i];
1955ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
1956ca15aa20SStefano Zampini     bv += blda;
19570754003eSLois Curfman McInnes   }
1958ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(newmat,&bv);CHKERRQ(ierr);
1959182d2002SSatish Balay 
1960182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
19616d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19626d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19630754003eSLois Curfman McInnes 
19640754003eSLois Curfman McInnes   /* Free work space */
196578b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
196678b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1967182d2002SSatish Balay   *B   = newmat;
19683a40ed3dSBarry Smith   PetscFunctionReturn(0);
19690754003eSLois Curfman McInnes }
19700754003eSLois Curfman McInnes 
19717dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1972905e6a2fSBarry Smith {
19736849ba73SBarry Smith   PetscErrorCode ierr;
197413f74950SBarry Smith   PetscInt       i;
1975905e6a2fSBarry Smith 
19763a40ed3dSBarry Smith   PetscFunctionBegin;
1977905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1978df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
1979905e6a2fSBarry Smith   }
1980905e6a2fSBarry Smith 
1981905e6a2fSBarry Smith   for (i=0; i<n; i++) {
19827dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1983905e6a2fSBarry Smith   }
19843a40ed3dSBarry Smith   PetscFunctionReturn(0);
1985905e6a2fSBarry Smith }
1986905e6a2fSBarry Smith 
1987e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
1988c0aa2d19SHong Zhang {
1989c0aa2d19SHong Zhang   PetscFunctionBegin;
1990c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1991c0aa2d19SHong Zhang }
1992c0aa2d19SHong Zhang 
1993e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
1994c0aa2d19SHong Zhang {
1995c0aa2d19SHong Zhang   PetscFunctionBegin;
1996c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1997c0aa2d19SHong Zhang }
1998c0aa2d19SHong Zhang 
1999e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
20004b0e389bSBarry Smith {
20014b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
20026849ba73SBarry Smith   PetscErrorCode    ierr;
2003ca15aa20SStefano Zampini   const PetscScalar *va;
2004ca15aa20SStefano Zampini   PetscScalar       *vb;
2005d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
20063a40ed3dSBarry Smith 
20073a40ed3dSBarry Smith   PetscFunctionBegin;
200833f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
200933f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
2010cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
20113a40ed3dSBarry Smith     PetscFunctionReturn(0);
20123a40ed3dSBarry Smith   }
2013e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
2014ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&va);CHKERRQ(ierr);
2015ca15aa20SStefano Zampini   ierr = MatDenseGetArray(B,&vb);CHKERRQ(ierr);
2016a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
20170dbb7854Svictorle     for (j=0; j<n; j++) {
2018ca15aa20SStefano Zampini       ierr = PetscArraycpy(vb+j*lda2,va+j*lda1,m);CHKERRQ(ierr);
2019a5ce6ee0Svictorle     }
2020a5ce6ee0Svictorle   } else {
2021ca15aa20SStefano Zampini     ierr = PetscArraycpy(vb,va,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2022a5ce6ee0Svictorle   }
2023ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(B,&vb);CHKERRQ(ierr);
2024ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&va);CHKERRQ(ierr);
2025ca15aa20SStefano Zampini   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2026ca15aa20SStefano Zampini   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2027273d9f13SBarry Smith   PetscFunctionReturn(0);
2028273d9f13SBarry Smith }
2029273d9f13SBarry Smith 
2030e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
2031273d9f13SBarry Smith {
2032dfbe8321SBarry Smith   PetscErrorCode ierr;
2033273d9f13SBarry Smith 
2034273d9f13SBarry Smith   PetscFunctionBegin;
2035*18992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
2036*18992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
2037*18992e5dSStefano Zampini   if (!A->preallocated) {
2038273d9f13SBarry Smith     ierr = MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
2039*18992e5dSStefano Zampini   }
20403a40ed3dSBarry Smith   PetscFunctionReturn(0);
20414b0e389bSBarry Smith }
20424b0e389bSBarry Smith 
2043ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2044ba337c44SJed Brown {
2045ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2046ca15aa20SStefano Zampini   PetscScalar    *aa;
2047ca15aa20SStefano Zampini   PetscErrorCode ierr;
2048ba337c44SJed Brown 
2049ba337c44SJed Brown   PetscFunctionBegin;
2050ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2051ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2052ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2053ba337c44SJed Brown   PetscFunctionReturn(0);
2054ba337c44SJed Brown }
2055ba337c44SJed Brown 
2056ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2057ba337c44SJed Brown {
2058ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2059ca15aa20SStefano Zampini   PetscScalar    *aa;
2060ca15aa20SStefano Zampini   PetscErrorCode ierr;
2061ba337c44SJed Brown 
2062ba337c44SJed Brown   PetscFunctionBegin;
2063ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2064ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2065ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2066ba337c44SJed Brown   PetscFunctionReturn(0);
2067ba337c44SJed Brown }
2068ba337c44SJed Brown 
2069ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_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] = PetscImaginaryPart(aa[i]);
2078ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2079ba337c44SJed Brown   PetscFunctionReturn(0);
2080ba337c44SJed Brown }
2081284134d9SBarry Smith 
2082a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
20834222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2084a9fe9ddaSSatish Balay {
2085ee16a9a1SHong Zhang   PetscErrorCode ierr;
2086d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
2087ca15aa20SStefano Zampini   PetscBool      flg;
2088a9fe9ddaSSatish Balay 
2089ee16a9a1SHong Zhang   PetscFunctionBegin;
20904222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
2091ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
20924222ddf1SHong Zhang   ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
2093*18992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2094ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2095ee16a9a1SHong Zhang }
2096a9fe9ddaSSatish Balay 
2097a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2098a9fe9ddaSSatish Balay {
209952c5f739Sprj-   Mat_SeqDense       *a,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
21000805154bSBarry Smith   PetscBLASInt       m,n,k;
2101ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2102ca15aa20SStefano Zampini   PetscScalar       *cv;
2103a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2104fd4e9aacSBarry Smith   PetscBool         flg;
2105c2916339SPierre Jolivet   PetscErrorCode    (*numeric)(Mat,Mat,Mat)=NULL;
2106c2916339SPierre Jolivet   PetscErrorCode    ierr;
2107a9fe9ddaSSatish Balay 
2108a9fe9ddaSSatish Balay   PetscFunctionBegin;
2109fd4e9aacSBarry Smith   /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/
2110fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
2111c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqAIJ_SeqDense;
2112a001520aSPierre Jolivet   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQBAIJ,&flg);CHKERRQ(ierr);
2113c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqBAIJ_SeqDense;
2114c2916339SPierre Jolivet   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQSBAIJ,&flg);CHKERRQ(ierr);
2115c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqSBAIJ_SeqDense;
211652c5f739Sprj-   ierr = PetscObjectTypeCompare((PetscObject)A,MATNEST,&flg);CHKERRQ(ierr);
2117c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_Nest_Dense;
2118c2916339SPierre Jolivet   if (numeric) {
2119c2916339SPierre Jolivet     C->ops->matmultnumeric = numeric;
2120c2916339SPierre Jolivet     ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
212152c5f739Sprj-     PetscFunctionReturn(0);
212252c5f739Sprj-   }
212352c5f739Sprj-   a = (Mat_SeqDense*)A->data;
21248208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
21258208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2126c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
212749d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
2128ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
2129ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
2130ca15aa20SStefano Zampini   ierr = MatDenseGetArray(C,&cv);CHKERRQ(ierr);
2131ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
2132ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2133ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
2134ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
2135ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(C,&cv);CHKERRQ(ierr);
2136a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2137a9fe9ddaSSatish Balay }
2138a9fe9ddaSSatish Balay 
21394222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
214069f65d41SStefano Zampini {
214169f65d41SStefano Zampini   PetscErrorCode ierr;
214269f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
2143ca15aa20SStefano Zampini   PetscBool      flg;
214469f65d41SStefano Zampini 
214569f65d41SStefano Zampini   PetscFunctionBegin;
21464222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
2147ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
21484222ddf1SHong Zhang   ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
2149*18992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
215069f65d41SStefano Zampini   PetscFunctionReturn(0);
215169f65d41SStefano Zampini }
215269f65d41SStefano Zampini 
215369f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
215469f65d41SStefano Zampini {
215569f65d41SStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
215669f65d41SStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
215769f65d41SStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
215869f65d41SStefano Zampini   PetscBLASInt   m,n,k;
215969f65d41SStefano Zampini   PetscScalar    _DOne=1.0,_DZero=0.0;
216069f65d41SStefano Zampini   PetscErrorCode ierr;
216169f65d41SStefano Zampini 
216269f65d41SStefano Zampini   PetscFunctionBegin;
216349d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
216449d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
216569f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
216649d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
216769f65d41SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2168ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
216969f65d41SStefano Zampini   PetscFunctionReturn(0);
217069f65d41SStefano Zampini }
217169f65d41SStefano Zampini 
21724222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2173a9fe9ddaSSatish Balay {
2174ee16a9a1SHong Zhang   PetscErrorCode ierr;
2175d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
2176ca15aa20SStefano Zampini   PetscBool      flg;
2177a9fe9ddaSSatish Balay 
2178ee16a9a1SHong Zhang   PetscFunctionBegin;
21794222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
2180ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
21814222ddf1SHong Zhang   ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
2182*18992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2183ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2184ee16a9a1SHong Zhang }
2185a9fe9ddaSSatish Balay 
218675648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2187a9fe9ddaSSatish Balay {
2188a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2189a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2190a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
21910805154bSBarry Smith   PetscBLASInt   m,n,k;
2192a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
2193c5df96a5SBarry Smith   PetscErrorCode ierr;
2194a9fe9ddaSSatish Balay 
2195a9fe9ddaSSatish Balay   PetscFunctionBegin;
21968208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
21978208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2198c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
219949d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
22005ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2201ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2202a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2203a9fe9ddaSSatish Balay }
2204985db425SBarry Smith 
22054222ddf1SHong Zhang /* ----------------------------------------------- */
22064222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
22074222ddf1SHong Zhang {
22084222ddf1SHong Zhang   PetscFunctionBegin;
22094222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
22104222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
22114222ddf1SHong Zhang   /* dense mat may not call MatProductSymbolic(), thus set C->ops->productnumeric here */
22124222ddf1SHong Zhang   C->ops->productnumeric  = MatProductNumeric_AB;
22134222ddf1SHong Zhang   PetscFunctionReturn(0);
22144222ddf1SHong Zhang }
22154222ddf1SHong Zhang 
22164222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
22174222ddf1SHong Zhang {
22184222ddf1SHong Zhang   PetscFunctionBegin;
22194222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
22204222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
22214222ddf1SHong Zhang   C->ops->productnumeric           = MatProductNumeric_AtB;
22224222ddf1SHong Zhang   PetscFunctionReturn(0);
22234222ddf1SHong Zhang }
22244222ddf1SHong Zhang 
22254222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
22264222ddf1SHong Zhang {
22274222ddf1SHong Zhang   PetscFunctionBegin;
22284222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
22294222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
22304222ddf1SHong Zhang   C->ops->productnumeric           = MatProductNumeric_ABt;
22314222ddf1SHong Zhang   PetscFunctionReturn(0);
22324222ddf1SHong Zhang }
22334222ddf1SHong Zhang 
22344222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_PtAP(Mat C)
22354222ddf1SHong Zhang {
22364222ddf1SHong Zhang   PetscFunctionBegin;
22374222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_Basic;
22384222ddf1SHong Zhang   PetscFunctionReturn(0);
22394222ddf1SHong Zhang }
22404222ddf1SHong Zhang 
22414222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
22424222ddf1SHong Zhang {
22434222ddf1SHong Zhang   PetscErrorCode ierr;
22444222ddf1SHong Zhang   Mat_Product    *product = C->product;
22454222ddf1SHong Zhang 
22464222ddf1SHong Zhang   PetscFunctionBegin;
22474222ddf1SHong Zhang   switch (product->type) {
22484222ddf1SHong Zhang   case MATPRODUCT_AB:
22494222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AB(C);CHKERRQ(ierr);
22504222ddf1SHong Zhang     break;
22514222ddf1SHong Zhang   case MATPRODUCT_AtB:
22524222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AtB(C);CHKERRQ(ierr);
22534222ddf1SHong Zhang     break;
22544222ddf1SHong Zhang   case MATPRODUCT_ABt:
22554222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_ABt(C);CHKERRQ(ierr);
22564222ddf1SHong Zhang     break;
22574222ddf1SHong Zhang   case MATPRODUCT_PtAP:
22584222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_PtAP(C);CHKERRQ(ierr);
22594222ddf1SHong Zhang     break;
2260544a5e07SHong Zhang   default: SETERRQ1(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProduct type %s is not supported for SeqDense and SeqDense matrices",MatProductTypes[product->type]);
22614222ddf1SHong Zhang   }
22624222ddf1SHong Zhang   PetscFunctionReturn(0);
22634222ddf1SHong Zhang }
22644222ddf1SHong Zhang /* ----------------------------------------------- */
22654222ddf1SHong Zhang 
2266e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2267985db425SBarry Smith {
2268985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2269985db425SBarry Smith   PetscErrorCode     ierr;
2270d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2271985db425SBarry Smith   PetscScalar        *x;
2272ca15aa20SStefano Zampini   const PetscScalar *aa;
2273985db425SBarry Smith 
2274985db425SBarry Smith   PetscFunctionBegin;
2275e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2276985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2277985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2278ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2279e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2280985db425SBarry Smith   for (i=0; i<m; i++) {
2281985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2282985db425SBarry Smith     for (j=1; j<n; j++) {
2283ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2284985db425SBarry Smith     }
2285985db425SBarry Smith   }
2286ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2287985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2288985db425SBarry Smith   PetscFunctionReturn(0);
2289985db425SBarry Smith }
2290985db425SBarry Smith 
2291e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2292985db425SBarry Smith {
2293985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2294985db425SBarry Smith   PetscErrorCode    ierr;
2295d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2296985db425SBarry Smith   PetscScalar       *x;
2297985db425SBarry Smith   PetscReal         atmp;
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++) {
23079189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2308985db425SBarry Smith     for (j=1; j<n; j++) {
2309ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2310985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2311985db425SBarry Smith     }
2312985db425SBarry Smith   }
2313ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2314985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2315985db425SBarry Smith   PetscFunctionReturn(0);
2316985db425SBarry Smith }
2317985db425SBarry Smith 
2318e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2319985db425SBarry Smith {
2320985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2321985db425SBarry Smith   PetscErrorCode    ierr;
2322d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2323985db425SBarry Smith   PetscScalar       *x;
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");
2328ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2329985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2330985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);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++) {
2333985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2334985db425SBarry Smith     for (j=1; j<n; j++) {
2335ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2336985db425SBarry Smith     }
2337985db425SBarry Smith   }
2338985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2339ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2340985db425SBarry Smith   PetscFunctionReturn(0);
2341985db425SBarry Smith }
2342985db425SBarry Smith 
2343e0877f53SBarry Smith static PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
23448d0534beSBarry Smith {
23458d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
23468d0534beSBarry Smith   PetscErrorCode    ierr;
23478d0534beSBarry Smith   PetscScalar       *x;
2348ca15aa20SStefano Zampini   const PetscScalar *aa;
23498d0534beSBarry Smith 
23508d0534beSBarry Smith   PetscFunctionBegin;
2351e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2352ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
23538d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2354ca15aa20SStefano Zampini   ierr = PetscArraycpy(x,aa+col*a->lda,A->rmap->n);CHKERRQ(ierr);
23558d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2356ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
23578d0534beSBarry Smith   PetscFunctionReturn(0);
23588d0534beSBarry Smith }
23598d0534beSBarry Smith 
236052c5f739Sprj- PETSC_INTERN PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
23610716a85fSBarry Smith {
23620716a85fSBarry Smith   PetscErrorCode    ierr;
23630716a85fSBarry Smith   PetscInt          i,j,m,n;
23641683a169SBarry Smith   const PetscScalar *a;
23650716a85fSBarry Smith 
23660716a85fSBarry Smith   PetscFunctionBegin;
23670716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2368580bdb30SBarry Smith   ierr = PetscArrayzero(norms,n);CHKERRQ(ierr);
23691683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&a);CHKERRQ(ierr);
23700716a85fSBarry Smith   if (type == NORM_2) {
23710716a85fSBarry Smith     for (i=0; i<n; i++) {
23720716a85fSBarry Smith       for (j=0; j<m; j++) {
23730716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
23740716a85fSBarry Smith       }
23750716a85fSBarry Smith       a += m;
23760716a85fSBarry Smith     }
23770716a85fSBarry Smith   } else if (type == NORM_1) {
23780716a85fSBarry Smith     for (i=0; i<n; i++) {
23790716a85fSBarry Smith       for (j=0; j<m; j++) {
23800716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
23810716a85fSBarry Smith       }
23820716a85fSBarry Smith       a += m;
23830716a85fSBarry Smith     }
23840716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
23850716a85fSBarry Smith     for (i=0; i<n; i++) {
23860716a85fSBarry Smith       for (j=0; j<m; j++) {
23870716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
23880716a85fSBarry Smith       }
23890716a85fSBarry Smith       a += m;
23900716a85fSBarry Smith     }
2391ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
23921683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&a);CHKERRQ(ierr);
23930716a85fSBarry Smith   if (type == NORM_2) {
23948f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
23950716a85fSBarry Smith   }
23960716a85fSBarry Smith   PetscFunctionReturn(0);
23970716a85fSBarry Smith }
23980716a85fSBarry Smith 
239973a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
240073a71a0fSBarry Smith {
240173a71a0fSBarry Smith   PetscErrorCode ierr;
240273a71a0fSBarry Smith   PetscScalar    *a;
240373a71a0fSBarry Smith   PetscInt       m,n,i;
240473a71a0fSBarry Smith 
240573a71a0fSBarry Smith   PetscFunctionBegin;
240673a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
24078c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
240873a71a0fSBarry Smith   for (i=0; i<m*n; i++) {
240973a71a0fSBarry Smith     ierr = PetscRandomGetValue(rctx,a+i);CHKERRQ(ierr);
241073a71a0fSBarry Smith   }
24118c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
241273a71a0fSBarry Smith   PetscFunctionReturn(0);
241373a71a0fSBarry Smith }
241473a71a0fSBarry Smith 
24153b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
24163b49f96aSBarry Smith {
24173b49f96aSBarry Smith   PetscFunctionBegin;
24183b49f96aSBarry Smith   *missing = PETSC_FALSE;
24193b49f96aSBarry Smith   PetscFunctionReturn(0);
24203b49f96aSBarry Smith }
242173a71a0fSBarry Smith 
2422ca15aa20SStefano Zampini /* vals is not const */
2423af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
242486aefd0dSHong Zhang {
2425ca15aa20SStefano Zampini   PetscErrorCode ierr;
242686aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2427ca15aa20SStefano Zampini   PetscScalar    *v;
242886aefd0dSHong Zhang 
242986aefd0dSHong Zhang   PetscFunctionBegin;
243086aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2431ca15aa20SStefano Zampini   ierr  = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2432ca15aa20SStefano Zampini   *vals = v+col*a->lda;
2433ca15aa20SStefano Zampini   ierr  = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
243486aefd0dSHong Zhang   PetscFunctionReturn(0);
243586aefd0dSHong Zhang }
243686aefd0dSHong Zhang 
2437af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
243886aefd0dSHong Zhang {
243986aefd0dSHong Zhang   PetscFunctionBegin;
244086aefd0dSHong Zhang   *vals = 0; /* user cannot accidently use the array later */
244186aefd0dSHong Zhang   PetscFunctionReturn(0);
244286aefd0dSHong Zhang }
2443abc3b08eSStefano Zampini 
2444289bc588SBarry Smith /* -------------------------------------------------------------------*/
2445a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2446905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2447905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2448905e6a2fSBarry Smith                                         MatMult_SeqDense,
244997304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
24507c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
24517c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2452db4efbfdSBarry Smith                                         0,
2453db4efbfdSBarry Smith                                         0,
2454db4efbfdSBarry Smith                                         0,
2455db4efbfdSBarry Smith                                 /* 10*/ 0,
2456905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2457905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
245841f059aeSBarry Smith                                         MatSOR_SeqDense,
2459ec8511deSBarry Smith                                         MatTranspose_SeqDense,
246097304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2461905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2462905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2463905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2464905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2465c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2466c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2467905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2468905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2469d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2470db4efbfdSBarry Smith                                         0,
2471db4efbfdSBarry Smith                                         0,
2472db4efbfdSBarry Smith                                         0,
2473db4efbfdSBarry Smith                                         0,
24744994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2475273d9f13SBarry Smith                                         0,
2476905e6a2fSBarry Smith                                         0,
247773a71a0fSBarry Smith                                         0,
247873a71a0fSBarry Smith                                         0,
2479d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2480a5ae1ecdSBarry Smith                                         0,
2481a5ae1ecdSBarry Smith                                         0,
2482a5ae1ecdSBarry Smith                                         0,
2483a5ae1ecdSBarry Smith                                         0,
2484d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
24857dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2486a5ae1ecdSBarry Smith                                         0,
24874b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2488a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2489d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2490a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
24917d68702bSBarry Smith                                         MatShift_Basic,
2492a5ae1ecdSBarry Smith                                         0,
24933f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
249473a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2495a5ae1ecdSBarry Smith                                         0,
2496a5ae1ecdSBarry Smith                                         0,
2497a5ae1ecdSBarry Smith                                         0,
2498a5ae1ecdSBarry Smith                                         0,
2499d519adbfSMatthew Knepley                                 /* 54*/ 0,
2500a5ae1ecdSBarry Smith                                         0,
2501a5ae1ecdSBarry Smith                                         0,
2502a5ae1ecdSBarry Smith                                         0,
2503a5ae1ecdSBarry Smith                                         0,
2504d519adbfSMatthew Knepley                                 /* 59*/ 0,
2505e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2506e03a110bSBarry Smith                                         MatView_SeqDense,
2507357abbc8SBarry Smith                                         0,
250897304618SKris Buschelman                                         0,
2509d519adbfSMatthew Knepley                                 /* 64*/ 0,
251097304618SKris Buschelman                                         0,
251197304618SKris Buschelman                                         0,
251297304618SKris Buschelman                                         0,
251397304618SKris Buschelman                                         0,
2514d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
251597304618SKris Buschelman                                         0,
251697304618SKris Buschelman                                         0,
251797304618SKris Buschelman                                         0,
251897304618SKris Buschelman                                         0,
2519d519adbfSMatthew Knepley                                 /* 74*/ 0,
252097304618SKris Buschelman                                         0,
252197304618SKris Buschelman                                         0,
252297304618SKris Buschelman                                         0,
252397304618SKris Buschelman                                         0,
2524d519adbfSMatthew Knepley                                 /* 79*/ 0,
252597304618SKris Buschelman                                         0,
252697304618SKris Buschelman                                         0,
252797304618SKris Buschelman                                         0,
25285bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2529865e5f61SKris Buschelman                                         0,
25301cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2531865e5f61SKris Buschelman                                         0,
2532865e5f61SKris Buschelman                                         0,
2533865e5f61SKris Buschelman                                         0,
25344222ddf1SHong Zhang                                 /* 89*/ 0,
25354222ddf1SHong Zhang                                         0,
2536a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
25374222ddf1SHong Zhang                                         0,
25384222ddf1SHong Zhang                                         0,
25394222ddf1SHong Zhang                                 /* 94*/ 0,
25404222ddf1SHong Zhang                                         0,
25414222ddf1SHong Zhang                                         0,
254269f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2543284134d9SBarry Smith                                         0,
25444222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
2545284134d9SBarry Smith                                         0,
2546284134d9SBarry Smith                                         0,
2547ba337c44SJed Brown                                         MatConjugate_SeqDense,
2548f73d5cc4SBarry Smith                                         0,
2549ba337c44SJed Brown                                 /*104*/ 0,
2550ba337c44SJed Brown                                         MatRealPart_SeqDense,
2551ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2552985db425SBarry Smith                                         0,
2553985db425SBarry Smith                                         0,
25548208b9aeSStefano Zampini                                 /*109*/ 0,
2555985db425SBarry Smith                                         0,
25568d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2557aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
25583b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2559aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2560aabbc4fbSShri Abhyankar                                         0,
2561aabbc4fbSShri Abhyankar                                         0,
2562aabbc4fbSShri Abhyankar                                         0,
2563aabbc4fbSShri Abhyankar                                         0,
2564aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2565aabbc4fbSShri Abhyankar                                         0,
2566aabbc4fbSShri Abhyankar                                         0,
25670716a85fSBarry Smith                                         0,
25680716a85fSBarry Smith                                         0,
25690716a85fSBarry Smith                                 /*124*/ 0,
25705df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
25715df89d91SHong Zhang                                         0,
25725df89d91SHong Zhang                                         0,
25735df89d91SHong Zhang                                         0,
25745df89d91SHong Zhang                                 /*129*/ 0,
25754222ddf1SHong Zhang                                         0,
25764222ddf1SHong Zhang                                         0,
257775648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
25783964eb88SJed Brown                                         0,
25793964eb88SJed Brown                                 /*134*/ 0,
25803964eb88SJed Brown                                         0,
25813964eb88SJed Brown                                         0,
25823964eb88SJed Brown                                         0,
25833964eb88SJed Brown                                         0,
25843964eb88SJed Brown                                 /*139*/ 0,
2585f9426fe0SMark Adams                                         0,
2586d528f656SJakub Kruzik                                         0,
2587d528f656SJakub Kruzik                                         0,
2588d528f656SJakub Kruzik                                         0,
25894222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
25904222ddf1SHong Zhang                                 /*145*/ 0,
25914222ddf1SHong Zhang                                         0,
25924222ddf1SHong Zhang                                         0
2593985db425SBarry Smith };
259490ace30eSBarry Smith 
25954b828684SBarry Smith /*@C
2596fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2597d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2598d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2599289bc588SBarry Smith 
2600d083f849SBarry Smith    Collective
2601db81eaa0SLois Curfman McInnes 
260220563c6bSBarry Smith    Input Parameters:
2603db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
26040c775827SLois Curfman McInnes .  m - number of rows
260518f449edSLois Curfman McInnes .  n - number of columns
26060298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2607dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
260820563c6bSBarry Smith 
260920563c6bSBarry Smith    Output Parameter:
261044cd7ae7SLois Curfman McInnes .  A - the matrix
261120563c6bSBarry Smith 
2612b259b22eSLois Curfman McInnes    Notes:
261318f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
261418f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
26150298fd71SBarry Smith    set data=NULL.
261618f449edSLois Curfman McInnes 
2617027ccd11SLois Curfman McInnes    Level: intermediate
2618027ccd11SLois Curfman McInnes 
261969b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
262020563c6bSBarry Smith @*/
26217087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2622289bc588SBarry Smith {
2623dfbe8321SBarry Smith   PetscErrorCode ierr;
26243b2fbd54SBarry Smith 
26253a40ed3dSBarry Smith   PetscFunctionBegin;
2626f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2627f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2628273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2629273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2630273d9f13SBarry Smith   PetscFunctionReturn(0);
2631273d9f13SBarry Smith }
2632273d9f13SBarry Smith 
2633273d9f13SBarry Smith /*@C
2634273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2635273d9f13SBarry Smith 
2636d083f849SBarry Smith    Collective
2637273d9f13SBarry Smith 
2638273d9f13SBarry Smith    Input Parameters:
26391c4f3114SJed Brown +  B - the matrix
26400298fd71SBarry Smith -  data - the array (or NULL)
2641273d9f13SBarry Smith 
2642273d9f13SBarry Smith    Notes:
2643273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2644273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2645284134d9SBarry Smith    need not call this routine.
2646273d9f13SBarry Smith 
2647273d9f13SBarry Smith    Level: intermediate
2648273d9f13SBarry Smith 
264969b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA()
2650867c911aSBarry Smith 
2651273d9f13SBarry Smith @*/
26527087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2653273d9f13SBarry Smith {
26544ac538c5SBarry Smith   PetscErrorCode ierr;
2655a23d5eceSKris Buschelman 
2656a23d5eceSKris Buschelman   PetscFunctionBegin;
26574ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2658a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2659a23d5eceSKris Buschelman }
2660a23d5eceSKris Buschelman 
26617087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2662a23d5eceSKris Buschelman {
2663273d9f13SBarry Smith   Mat_SeqDense   *b;
2664dfbe8321SBarry Smith   PetscErrorCode ierr;
2665273d9f13SBarry Smith 
2666273d9f13SBarry Smith   PetscFunctionBegin;
2667273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2668a868139aSShri Abhyankar 
266934ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
267034ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
267134ef9618SShri Abhyankar 
2672273d9f13SBarry Smith   b       = (Mat_SeqDense*)B->data;
267386d161a7SShri Abhyankar   b->Mmax = B->rmap->n;
267486d161a7SShri Abhyankar   b->Nmax = B->cmap->n;
267586d161a7SShri Abhyankar   if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n;
267686d161a7SShri Abhyankar 
2677220afb94SBarry Smith   ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr);
26789e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
26799e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2680e92229d0SSatish Balay     ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr);
26813bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
26822205254eSKarl Rupp 
26839e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2684273d9f13SBarry Smith   } else { /* user-allocated storage */
26859e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2686273d9f13SBarry Smith     b->v          = data;
2687273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2688273d9f13SBarry Smith   }
26890450473dSBarry Smith   B->assembled = PETSC_TRUE;
2690273d9f13SBarry Smith   PetscFunctionReturn(0);
2691273d9f13SBarry Smith }
2692273d9f13SBarry Smith 
269365b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2694cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
26958baccfbdSHong Zhang {
2696d77f618aSHong Zhang   Mat               mat_elemental;
2697d77f618aSHong Zhang   PetscErrorCode    ierr;
26981683a169SBarry Smith   const PetscScalar *array;
26991683a169SBarry Smith   PetscScalar       *v_colwise;
2700d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2701d77f618aSHong Zhang 
27028baccfbdSHong Zhang   PetscFunctionBegin;
2703d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
27041683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&array);CHKERRQ(ierr);
2705d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2706d77f618aSHong Zhang   k = 0;
2707d77f618aSHong Zhang   for (j=0; j<N; j++) {
2708d77f618aSHong Zhang     cols[j] = j;
2709d77f618aSHong Zhang     for (i=0; i<M; i++) {
2710d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2711d77f618aSHong Zhang     }
2712d77f618aSHong Zhang   }
2713d77f618aSHong Zhang   for (i=0; i<M; i++) {
2714d77f618aSHong Zhang     rows[i] = i;
2715d77f618aSHong Zhang   }
27161683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&array);CHKERRQ(ierr);
2717d77f618aSHong Zhang 
2718d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2719d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2720d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2721d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2722d77f618aSHong Zhang 
2723d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2724d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2725d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2726d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2727d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2728d77f618aSHong Zhang 
2729511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
273028be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2731d77f618aSHong Zhang   } else {
2732d77f618aSHong Zhang     *newmat = mat_elemental;
2733d77f618aSHong Zhang   }
27348baccfbdSHong Zhang   PetscFunctionReturn(0);
27358baccfbdSHong Zhang }
273665b80a83SHong Zhang #endif
27378baccfbdSHong Zhang 
27381b807ce4Svictorle /*@C
27391b807ce4Svictorle   MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array
27401b807ce4Svictorle 
27411b807ce4Svictorle   Input parameter:
27421b807ce4Svictorle + A - the matrix
27431b807ce4Svictorle - lda - the leading dimension
27441b807ce4Svictorle 
27451b807ce4Svictorle   Notes:
2746867c911aSBarry Smith   This routine is to be used in conjunction with MatSeqDenseSetPreallocation();
27471b807ce4Svictorle   it asserts that the preallocation has a leading dimension (the LDA parameter
27481b807ce4Svictorle   of Blas and Lapack fame) larger than M, the first dimension of the matrix.
27491b807ce4Svictorle 
27501b807ce4Svictorle   Level: intermediate
27511b807ce4Svictorle 
2752284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize()
2753867c911aSBarry Smith 
27541b807ce4Svictorle @*/
27557087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetLDA(Mat B,PetscInt lda)
27561b807ce4Svictorle {
27571b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
275821a2c019SBarry Smith 
27591b807ce4Svictorle   PetscFunctionBegin;
2760e32f2f54SBarry 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);
27611b807ce4Svictorle   b->lda       = lda;
276221a2c019SBarry Smith   b->changelda = PETSC_FALSE;
276321a2c019SBarry Smith   b->Mmax      = PetscMax(b->Mmax,lda);
27641b807ce4Svictorle   PetscFunctionReturn(0);
27651b807ce4Svictorle }
27661b807ce4Svictorle 
2767d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
2768d528f656SJakub Kruzik {
2769d528f656SJakub Kruzik   PetscErrorCode ierr;
2770d528f656SJakub Kruzik   PetscMPIInt    size;
2771d528f656SJakub Kruzik 
2772d528f656SJakub Kruzik   PetscFunctionBegin;
2773d528f656SJakub Kruzik   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2774d528f656SJakub Kruzik   if (size == 1) {
2775d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
2776d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
2777d528f656SJakub Kruzik     } else {
2778d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2779d528f656SJakub Kruzik     }
2780d528f656SJakub Kruzik   } else {
2781d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
2782d528f656SJakub Kruzik   }
2783d528f656SJakub Kruzik   PetscFunctionReturn(0);
2784d528f656SJakub Kruzik }
2785d528f656SJakub Kruzik 
27860bad9183SKris Buschelman /*MC
2787fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
27880bad9183SKris Buschelman 
27890bad9183SKris Buschelman    Options Database Keys:
27900bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
27910bad9183SKris Buschelman 
27920bad9183SKris Buschelman   Level: beginner
27930bad9183SKris Buschelman 
279489665df3SBarry Smith .seealso: MatCreateSeqDense()
279589665df3SBarry Smith 
27960bad9183SKris Buschelman M*/
2797ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
2798273d9f13SBarry Smith {
2799273d9f13SBarry Smith   Mat_SeqDense   *b;
2800dfbe8321SBarry Smith   PetscErrorCode ierr;
28017c334f02SBarry Smith   PetscMPIInt    size;
2802273d9f13SBarry Smith 
2803273d9f13SBarry Smith   PetscFunctionBegin;
2804ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
2805e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
280655659b69SBarry Smith 
2807b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
2808549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
280944cd7ae7SLois Curfman McInnes   B->data = (void*)b;
281018f449edSLois Curfman McInnes 
2811273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
28124e220ebcSLois Curfman McInnes 
281349a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
2814bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
28158572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2816d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
2817d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
28188572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2819715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2820bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
28218baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
28228baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
28238baccfbdSHong Zhang #endif
28242bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
28252bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA);CHKERRQ(ierr);
28264222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
28274222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
28284222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaijcusparse_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
28292bf066beSStefano Zampini #endif
2830bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
28314222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
28324222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
2833bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2834bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
28354222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
2836a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqbaij_seqdense_C",MatMatMultSymbolic_SeqBAIJ_SeqDense);CHKERRQ(ierr);
2837a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqbaij_seqdense_C",MatMatMultNumeric_SeqBAIJ_SeqDense);CHKERRQ(ierr);
28384222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
2839c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqsbaij_seqdense_C",MatMatMultSymbolic_SeqSBAIJ_SeqDense);CHKERRQ(ierr);
2840c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqsbaij_seqdense_C",MatMatMultNumeric_SeqSBAIJ_SeqDense);CHKERRQ(ierr);
28414099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijperm_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28424099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijperm_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2843e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijsell_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2844e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijsell_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
284596e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijmkl_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
284696e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijmkl_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
284752c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_nest_seqdense_C",MatMatMultSymbolic_Nest_Dense);CHKERRQ(ierr);
284852c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_nest_seqdense_C",MatMatMultNumeric_Nest_Dense);CHKERRQ(ierr);
284996e6d5c4SRichard Tran Mills 
28503bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28513bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
28524099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28534099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2854e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2855e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
285696e6d5c4SRichard Tran Mills 
285796e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
285896e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2859af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
2860af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
286117667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
28623a40ed3dSBarry Smith   PetscFunctionReturn(0);
2863289bc588SBarry Smith }
286486aefd0dSHong Zhang 
286586aefd0dSHong Zhang /*@C
2866af53bab2SHong 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.
286786aefd0dSHong Zhang 
286886aefd0dSHong Zhang    Not Collective
286986aefd0dSHong Zhang 
287086aefd0dSHong Zhang    Input Parameter:
287186aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
287286aefd0dSHong Zhang -  col - column index
287386aefd0dSHong Zhang 
287486aefd0dSHong Zhang    Output Parameter:
287586aefd0dSHong Zhang .  vals - pointer to the data
287686aefd0dSHong Zhang 
287786aefd0dSHong Zhang    Level: intermediate
287886aefd0dSHong Zhang 
287986aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
288086aefd0dSHong Zhang @*/
288186aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
288286aefd0dSHong Zhang {
288386aefd0dSHong Zhang   PetscErrorCode ierr;
288486aefd0dSHong Zhang 
288586aefd0dSHong Zhang   PetscFunctionBegin;
288686aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
288786aefd0dSHong Zhang   PetscFunctionReturn(0);
288886aefd0dSHong Zhang }
288986aefd0dSHong Zhang 
289086aefd0dSHong Zhang /*@C
289186aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
289286aefd0dSHong Zhang 
289386aefd0dSHong Zhang    Not Collective
289486aefd0dSHong Zhang 
289586aefd0dSHong Zhang    Input Parameter:
289686aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
289786aefd0dSHong Zhang 
289886aefd0dSHong Zhang    Output Parameter:
289986aefd0dSHong Zhang .  vals - pointer to the data
290086aefd0dSHong Zhang 
290186aefd0dSHong Zhang    Level: intermediate
290286aefd0dSHong Zhang 
290386aefd0dSHong Zhang .seealso: MatDenseGetColumn()
290486aefd0dSHong Zhang @*/
290586aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
290686aefd0dSHong Zhang {
290786aefd0dSHong Zhang   PetscErrorCode ierr;
290886aefd0dSHong Zhang 
290986aefd0dSHong Zhang   PetscFunctionBegin;
291086aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
291186aefd0dSHong Zhang   PetscFunctionReturn(0);
291286aefd0dSHong Zhang }
2913