xref: /petsc/src/mat/impls/dense/seq/dense.c (revision cf9c20a2d58da010f7c4712defbcdf61cc8f72b5)
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;
10576bd3646SJed Brown   if (PetscDefined(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     }
11176bd3646SJed Brown   }
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;}
916*cf9c20a2SJed Brown         if (PetscUnlikelyDebug(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);
917289bc588SBarry Smith         for (i=0; i<m; i++) {
918cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
919*cf9c20a2SJed Brown           if (PetscUnlikelyDebug(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);
920ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
921289bc588SBarry Smith         }
922289bc588SBarry Smith       }
9233a40ed3dSBarry Smith     } else {
924289bc588SBarry Smith       for (j=0; j<n; j++) {
925cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
926*cf9c20a2SJed Brown         if (PetscUnlikelyDebug(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);
927289bc588SBarry Smith         for (i=0; i<m; i++) {
928cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
929*cf9c20a2SJed Brown           if (PetscUnlikelyDebug(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);
930ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
931289bc588SBarry Smith         }
932289bc588SBarry Smith       }
933289bc588SBarry Smith     }
9343a40ed3dSBarry Smith   } else {
935dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
936e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
937cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
938*cf9c20a2SJed Brown         if (PetscUnlikelyDebug(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);
939e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
940cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
941*cf9c20a2SJed Brown           if (PetscUnlikelyDebug(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);
942ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
943e8d4e0b9SBarry Smith         }
944e8d4e0b9SBarry Smith       }
9453a40ed3dSBarry Smith     } else {
946289bc588SBarry Smith       for (i=0; i<m; i++) {
947cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
948*cf9c20a2SJed Brown         if (PetscUnlikelyDebug(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);
949289bc588SBarry Smith         for (j=0; j<n; j++) {
950cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
951*cf9c20a2SJed Brown           if (PetscUnlikelyDebug(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);
952ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
953289bc588SBarry Smith         }
954289bc588SBarry Smith       }
955289bc588SBarry Smith     }
956e8d4e0b9SBarry Smith   }
957ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
958ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
959c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
960c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
961ca15aa20SStefano Zampini #endif
962ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&av);CHKERRQ(ierr);
963ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
964c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
965ca15aa20SStefano Zampini #endif
9663a40ed3dSBarry Smith   PetscFunctionReturn(0);
967289bc588SBarry Smith }
968e8d4e0b9SBarry Smith 
969e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
970ae80bb75SLois Curfman McInnes {
971ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
972ca15aa20SStefano Zampini   const PetscScalar *vv;
97313f74950SBarry Smith   PetscInt          i,j;
974ca15aa20SStefano Zampini   PetscErrorCode    ierr;
975ae80bb75SLois Curfman McInnes 
9763a40ed3dSBarry Smith   PetscFunctionBegin;
977ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
978ae80bb75SLois Curfman McInnes   /* row-oriented output */
979ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
98097e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
981e32f2f54SBarry 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);
982ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
9836f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
984e32f2f54SBarry 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);
985ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
986ae80bb75SLois Curfman McInnes     }
987ae80bb75SLois Curfman McInnes   }
988ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
9893a40ed3dSBarry Smith   PetscFunctionReturn(0);
990ae80bb75SLois Curfman McInnes }
991ae80bb75SLois Curfman McInnes 
992289bc588SBarry Smith /* -----------------------------------------------------------------*/
993289bc588SBarry Smith 
9948491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
995aabbc4fbSShri Abhyankar {
996aabbc4fbSShri Abhyankar   PetscErrorCode    ierr;
9978491ab44SLisandro Dalcin   PetscBool         skipHeader;
9988491ab44SLisandro Dalcin   PetscViewerFormat format;
9998491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
10008491ab44SLisandro Dalcin   const PetscScalar *v;
10018491ab44SLisandro Dalcin   PetscScalar       *vwork;
1002aabbc4fbSShri Abhyankar 
1003aabbc4fbSShri Abhyankar   PetscFunctionBegin;
10048491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
10058491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
10068491ab44SLisandro Dalcin   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
10078491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1008aabbc4fbSShri Abhyankar 
10098491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
10108491ab44SLisandro Dalcin 
10118491ab44SLisandro Dalcin   /* write matrix header */
10128491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
10138491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
10148491ab44SLisandro Dalcin   if (!skipHeader) {ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);}
10158491ab44SLisandro Dalcin 
10168491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
10178491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
10188491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
10198491ab44SLisandro Dalcin     /* store row lengths for each row */
10208491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
10218491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
10228491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
10238491ab44SLisandro Dalcin     /* store column indices (zero start index) */
10248491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
10258491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
10268491ab44SLisandro Dalcin         iwork[k] = j;
10278491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
10288491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
10298491ab44SLisandro Dalcin   }
10308491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
10318491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
10328491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
10338491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
10348491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
10358491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
10368491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
10378491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
10388491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
10398491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
10408491ab44SLisandro Dalcin   PetscFunctionReturn(0);
10418491ab44SLisandro Dalcin }
10428491ab44SLisandro Dalcin 
10438491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
10448491ab44SLisandro Dalcin {
10458491ab44SLisandro Dalcin   PetscErrorCode ierr;
10468491ab44SLisandro Dalcin   PetscBool      skipHeader;
10478491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
10488491ab44SLisandro Dalcin   PetscInt       rows,cols;
10498491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
10508491ab44SLisandro Dalcin 
10518491ab44SLisandro Dalcin   PetscFunctionBegin;
10528491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
10538491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
10548491ab44SLisandro Dalcin 
10558491ab44SLisandro Dalcin   if (!skipHeader) {
10568491ab44SLisandro Dalcin     ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
10578491ab44SLisandro Dalcin     if (header[0] != MAT_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
10588491ab44SLisandro Dalcin     M = header[1]; N = header[2];
10598491ab44SLisandro Dalcin     if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M);
10608491ab44SLisandro Dalcin     if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N);
10618491ab44SLisandro Dalcin     nz = header[3];
10628491ab44SLisandro Dalcin     if (nz != MATRIX_BINARY_FORMAT_DENSE && nz < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %D in file",nz);
1063aabbc4fbSShri Abhyankar   } else {
10648491ab44SLisandro Dalcin     ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
10658491ab44SLisandro 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");
10668491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1067e6324fbbSBarry Smith   }
1068aabbc4fbSShri Abhyankar 
10698491ab44SLisandro Dalcin   /* setup global sizes if not set */
10708491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
10718491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
10728491ab44SLisandro Dalcin   ierr = MatSetUp(mat);CHKERRQ(ierr);
10738491ab44SLisandro Dalcin   /* check if global sizes are correct */
10748491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
10758491ab44SLisandro 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);
1076aabbc4fbSShri Abhyankar 
10778491ab44SLisandro Dalcin   ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
10788491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
10798491ab44SLisandro Dalcin   ierr = MatDenseGetArray(mat,&v);CHKERRQ(ierr);
10808491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
10818491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
10828491ab44SLisandro Dalcin     PetscInt nnz = m*N;
10838491ab44SLisandro Dalcin     /* read in matrix values */
10848491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&vwork);CHKERRQ(ierr);
10858491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
10868491ab44SLisandro Dalcin     /* store values in column major order */
10878491ab44SLisandro Dalcin     for (j=0; j<N; j++)
10888491ab44SLisandro Dalcin       for (i=0; i<m; i++)
10898491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
10908491ab44SLisandro Dalcin     ierr = PetscFree(vwork);CHKERRQ(ierr);
10918491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
10928491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
10938491ab44SLisandro Dalcin     /* read in row lengths */
10948491ab44SLisandro Dalcin     ierr = PetscMalloc1(m,&rlens);CHKERRQ(ierr);
10958491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
10968491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
10978491ab44SLisandro Dalcin     /* read in column indices and values */
10988491ab44SLisandro Dalcin     ierr = PetscMalloc2(nnz,&icols,nnz,&vwork);CHKERRQ(ierr);
10998491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
11008491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
11018491ab44SLisandro Dalcin     /* store values in column major order */
11028491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
11038491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
11048491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
11058491ab44SLisandro Dalcin     ierr = PetscFree(rlens);CHKERRQ(ierr);
11068491ab44SLisandro Dalcin     ierr = PetscFree2(icols,vwork);CHKERRQ(ierr);
1107aabbc4fbSShri Abhyankar   }
11088491ab44SLisandro Dalcin   ierr = MatDenseRestoreArray(mat,&v);CHKERRQ(ierr);
11098491ab44SLisandro Dalcin   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
11108491ab44SLisandro Dalcin   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1111aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1112aabbc4fbSShri Abhyankar }
1113aabbc4fbSShri Abhyankar 
1114eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1115eb91f321SVaclav Hapla {
1116eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1117eb91f321SVaclav Hapla   PetscErrorCode ierr;
1118eb91f321SVaclav Hapla 
1119eb91f321SVaclav Hapla   PetscFunctionBegin;
1120eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1121eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1122eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
1123eb91f321SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1124eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1125eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1126eb91f321SVaclav Hapla   if (isbinary) {
11278491ab44SLisandro Dalcin     ierr = MatLoad_Dense_Binary(newMat,viewer);CHKERRQ(ierr);
1128eb91f321SVaclav Hapla   } else if (ishdf5) {
1129eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
1130eb91f321SVaclav Hapla     ierr = MatLoad_Dense_HDF5(newMat,viewer);CHKERRQ(ierr);
1131eb91f321SVaclav Hapla #else
1132eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1133eb91f321SVaclav Hapla #endif
1134eb91f321SVaclav Hapla   } else {
1135eb91f321SVaclav 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);
1136eb91f321SVaclav Hapla   }
1137eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1138eb91f321SVaclav Hapla }
1139eb91f321SVaclav Hapla 
11406849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1141289bc588SBarry Smith {
1142932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1143dfbe8321SBarry Smith   PetscErrorCode    ierr;
114413f74950SBarry Smith   PetscInt          i,j;
11452dcb1b2aSMatthew Knepley   const char        *name;
1146ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1147f3ef73ceSBarry Smith   PetscViewerFormat format;
11485f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1149ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
11505f481a85SSatish Balay #endif
1151932b0c3eSLois Curfman McInnes 
11523a40ed3dSBarry Smith   PetscFunctionBegin;
1153ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1154b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1155456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
11563a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1157fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1158d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1159d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1160ca15aa20SStefano Zampini       v    = av + i;
116177431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1162d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1163aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1164329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
116557622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1166329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
116757622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
11686831982aSBarry Smith         }
116980cd9d93SLois Curfman McInnes #else
11706831982aSBarry Smith         if (*v) {
117157622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
11726831982aSBarry Smith         }
117380cd9d93SLois Curfman McInnes #endif
11741b807ce4Svictorle         v += a->lda;
117580cd9d93SLois Curfman McInnes       }
1176b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
117780cd9d93SLois Curfman McInnes     }
1178d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
11793a40ed3dSBarry Smith   } else {
1180d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1181aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
118247989497SBarry Smith     /* determine if matrix has all real values */
1183ca15aa20SStefano Zampini     v = av;
1184d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1185ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
118647989497SBarry Smith     }
118747989497SBarry Smith #endif
1188fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
11893a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1190d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1191d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1192fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1193ffac6cdbSBarry Smith     }
1194ffac6cdbSBarry Smith 
1195d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1196ca15aa20SStefano Zampini       v = av + i;
1197d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1198aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
119947989497SBarry Smith         if (allreal) {
1200c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
120147989497SBarry Smith         } else {
1202c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
120347989497SBarry Smith         }
1204289bc588SBarry Smith #else
1205c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1206289bc588SBarry Smith #endif
12071b807ce4Svictorle         v += a->lda;
1208289bc588SBarry Smith       }
1209b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1210289bc588SBarry Smith     }
1211fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1212b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1213ffac6cdbSBarry Smith     }
1214d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1215da3a660dSBarry Smith   }
1216ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1217b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
12183a40ed3dSBarry Smith   PetscFunctionReturn(0);
1219289bc588SBarry Smith }
1220289bc588SBarry Smith 
12218491ab44SLisandro Dalcin static PetscErrorCode MatView_SeqDense_Binary(Mat mat,PetscViewer viewer)
1222932b0c3eSLois Curfman McInnes {
12236849ba73SBarry Smith   PetscErrorCode    ierr;
1224f4403165SShri Abhyankar   PetscViewerFormat format;
12258491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
12268491ab44SLisandro Dalcin   const PetscScalar *v;
12278491ab44SLisandro Dalcin   PetscScalar       *vwork;
1228932b0c3eSLois Curfman McInnes 
12293a40ed3dSBarry Smith   PetscFunctionBegin;
12308491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
12318491ab44SLisandro Dalcin 
1232f4403165SShri Abhyankar   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
12338491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
12342205254eSKarl Rupp 
12358491ab44SLisandro Dalcin   /* write matrix header */
12368491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
12378491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
12388491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);
12392205254eSKarl Rupp 
12408491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
12418491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
12428491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
12438491ab44SLisandro Dalcin     /* store row lengths for each row */
12448491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
12458491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
12468491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWrite(viewer,iwork,m,PETSC_INT);CHKERRQ(ierr);
1247932b0c3eSLois Curfman McInnes     /* store column indices (zero start index) */
12488491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
12498491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
12508491ab44SLisandro Dalcin         iwork[k] = j;
12518491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWrite(viewer,iwork,nnz,PETSC_INT);CHKERRQ(ierr);
12528491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
1253932b0c3eSLois Curfman McInnes   }
12548491ab44SLisandro Dalcin   /* store the matrix values as a dense matrix in row major order */
12558491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
12568491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
12578491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
12588491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
12598491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
12608491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
12618491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
12628491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWrite(viewer,vwork,m*N,PETSC_SCALAR);CHKERRQ(ierr);
12638491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
12643a40ed3dSBarry Smith   PetscFunctionReturn(0);
1265932b0c3eSLois Curfman McInnes }
1266932b0c3eSLois Curfman McInnes 
12679804daf3SBarry Smith #include <petscdraw.h>
1268e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1269f1af5d2fSBarry Smith {
1270f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
12716849ba73SBarry Smith   PetscErrorCode    ierr;
1272383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1273383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1274ca15aa20SStefano Zampini   const PetscScalar *v;
1275b0a32e0cSBarry Smith   PetscViewer       viewer;
1276b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1277f3ef73ceSBarry Smith   PetscViewerFormat format;
1278f1af5d2fSBarry Smith 
1279f1af5d2fSBarry Smith   PetscFunctionBegin;
1280f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1281b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1282b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1283f1af5d2fSBarry Smith 
1284f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1285ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1286fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1287383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1288f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1289f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1290383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1291f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1292f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1293f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1294ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1295ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1296ca15aa20SStefano Zampini         else continue;
1297b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1298f1af5d2fSBarry Smith       }
1299f1af5d2fSBarry Smith     }
1300383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1301f1af5d2fSBarry Smith   } else {
1302f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1303f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1304b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1305b05fc000SLisandro Dalcin     PetscDraw popup;
1306b05fc000SLisandro Dalcin 
1307f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1308f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1309f1af5d2fSBarry Smith     }
1310383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1311b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
131245f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1313383922c3SLisandro Dalcin 
1314383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1315f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1316f1af5d2fSBarry Smith       x_l = j;
1317f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1318f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1319f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1320f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1321b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1322b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1323f1af5d2fSBarry Smith       }
1324f1af5d2fSBarry Smith     }
1325383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1326f1af5d2fSBarry Smith   }
1327ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1328f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1329f1af5d2fSBarry Smith }
1330f1af5d2fSBarry Smith 
1331e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1332f1af5d2fSBarry Smith {
1333b0a32e0cSBarry Smith   PetscDraw      draw;
1334ace3abfcSBarry Smith   PetscBool      isnull;
1335329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1336dfbe8321SBarry Smith   PetscErrorCode ierr;
1337f1af5d2fSBarry Smith 
1338f1af5d2fSBarry Smith   PetscFunctionBegin;
1339b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1340b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1341abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1342f1af5d2fSBarry Smith 
1343d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1344f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1345b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1346832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1347b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
13480298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1349832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1350f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1351f1af5d2fSBarry Smith }
1352f1af5d2fSBarry Smith 
1353dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1354932b0c3eSLois Curfman McInnes {
1355dfbe8321SBarry Smith   PetscErrorCode ierr;
1356ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1357932b0c3eSLois Curfman McInnes 
13583a40ed3dSBarry Smith   PetscFunctionBegin;
1359251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1360251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1361251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
13620f5bd95cSBarry Smith 
1363c45a1595SBarry Smith   if (iascii) {
1364c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
13650f5bd95cSBarry Smith   } else if (isbinary) {
13663a40ed3dSBarry Smith     ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr);
1367f1af5d2fSBarry Smith   } else if (isdraw) {
1368f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1369932b0c3eSLois Curfman McInnes   }
13703a40ed3dSBarry Smith   PetscFunctionReturn(0);
1371932b0c3eSLois Curfman McInnes }
1372289bc588SBarry Smith 
1373d3042a70SBarry Smith static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar array[])
1374d3042a70SBarry Smith {
1375d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1376d3042a70SBarry Smith 
1377d3042a70SBarry Smith   PetscFunctionBegin;
1378d3042a70SBarry Smith   a->unplacedarray       = a->v;
1379d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1380d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1381ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1382c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1383ca15aa20SStefano Zampini #endif
1384d3042a70SBarry Smith   PetscFunctionReturn(0);
1385d3042a70SBarry Smith }
1386d3042a70SBarry Smith 
1387d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1388d3042a70SBarry Smith {
1389d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1390d3042a70SBarry Smith 
1391d3042a70SBarry Smith   PetscFunctionBegin;
1392d3042a70SBarry Smith   a->v             = a->unplacedarray;
1393d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1394d3042a70SBarry Smith   a->unplacedarray = NULL;
1395ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1396c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1397ca15aa20SStefano Zampini #endif
1398d3042a70SBarry Smith   PetscFunctionReturn(0);
1399d3042a70SBarry Smith }
1400d3042a70SBarry Smith 
1401ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1402289bc588SBarry Smith {
1403ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1404dfbe8321SBarry Smith   PetscErrorCode ierr;
140590f02eecSBarry Smith 
14063a40ed3dSBarry Smith   PetscFunctionBegin;
1407aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1408d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1409a5a9c739SBarry Smith #endif
141005b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1411a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1412abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
14136857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1414bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1415dbd8c25aSHong Zhang 
1416dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
141749a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1418bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
141952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
1420d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1421d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
142252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL);CHKERRQ(ierr);
142352c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL);CHKERRQ(ierr);
14248baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
14258baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
14268baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
14278baccfbdSHong Zhang #endif
14282bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
14292bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL);CHKERRQ(ierr);
14304222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL);CHKERRQ(ierr);
14314222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL);CHKERRQ(ierr);
14324222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaijcusparse_seqdense_C",NULL);CHKERRQ(ierr);
14332bf066beSStefano Zampini #endif
1434bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
14354222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14364222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL);CHKERRQ(ierr);
1437bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1438bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14394222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1440a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1441a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
14424222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
1443c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
1444c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
144552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
144652c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
144752c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
144852c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
144952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
145052c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
145152c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_nest_seqdense_C",NULL);CHKERRQ(ierr);
145252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_nest_seqdense_C",NULL);CHKERRQ(ierr);
145352c5f739Sprj- 
14543bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14553bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
145652c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
145752c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
145852c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
145952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
146052c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
146152c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
146286aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
146386aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
14643a40ed3dSBarry Smith   PetscFunctionReturn(0);
1465289bc588SBarry Smith }
1466289bc588SBarry Smith 
1467e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1468289bc588SBarry Smith {
1469c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
14706849ba73SBarry Smith   PetscErrorCode ierr;
147113f74950SBarry Smith   PetscInt       k,j,m,n,M;
147287828ca2SBarry Smith   PetscScalar    *v,tmp;
147348b35521SBarry Smith 
14743a40ed3dSBarry Smith   PetscFunctionBegin;
1475ca15aa20SStefano Zampini   m = A->rmap->n; M = mat->lda; n = A->cmap->n;
14762847e3fdSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX && m == n) { /* in place transpose */
1477ca15aa20SStefano Zampini     ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1478d3e5ee88SLois Curfman McInnes     for (j=0; j<m; j++) {
1479289bc588SBarry Smith       for (k=0; k<j; k++) {
14801b807ce4Svictorle         tmp        = v[j + k*M];
14811b807ce4Svictorle         v[j + k*M] = v[k + j*M];
14821b807ce4Svictorle         v[k + j*M] = tmp;
1483289bc588SBarry Smith       }
1484289bc588SBarry Smith     }
1485ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
14863a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1487d3e5ee88SLois Curfman McInnes     Mat          tmat;
1488ec8511deSBarry Smith     Mat_SeqDense *tmatd;
148987828ca2SBarry Smith     PetscScalar  *v2;
1490af36a384SStefano Zampini     PetscInt     M2;
1491ea709b57SSatish Balay 
14922847e3fdSStefano Zampini     if (reuse != MAT_REUSE_MATRIX) {
1493ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1494d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
14957adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
14960298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1497ca15aa20SStefano Zampini     } else tmat = *matout;
1498ca15aa20SStefano Zampini 
1499ca15aa20SStefano Zampini     ierr  = MatDenseGetArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
1500ca15aa20SStefano Zampini     ierr  = MatDenseGetArray(tmat,&v2);CHKERRQ(ierr);
1501ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1502ca15aa20SStefano Zampini     M2    = tmatd->lda;
1503d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1504af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1505d3e5ee88SLois Curfman McInnes     }
1506ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(tmat,&v2);CHKERRQ(ierr);
1507ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
15086d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15096d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15102847e3fdSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) *matout = tmat;
15112847e3fdSStefano Zampini     else {
15122847e3fdSStefano Zampini       ierr = MatHeaderMerge(A,&tmat);CHKERRQ(ierr);
15132847e3fdSStefano Zampini     }
151448b35521SBarry Smith   }
15153a40ed3dSBarry Smith   PetscFunctionReturn(0);
1516289bc588SBarry Smith }
1517289bc588SBarry Smith 
1518e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1519289bc588SBarry Smith {
1520c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1521c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1522ca15aa20SStefano Zampini   PetscInt          i;
1523ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
1524ca15aa20SStefano Zampini   PetscErrorCode    ierr;
15259ea5d5aeSSatish Balay 
15263a40ed3dSBarry Smith   PetscFunctionBegin;
1527d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1528d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1529ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A1,&v1);CHKERRQ(ierr);
1530ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A2,&v2);CHKERRQ(ierr);
1531ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
1532ca15aa20SStefano Zampini     ierr = PetscArraycmp(v1,v2,A1->rmap->n,flg);CHKERRQ(ierr);
1533ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1534ca15aa20SStefano Zampini     v1 += mat1->lda;
1535ca15aa20SStefano Zampini     v2 += mat2->lda;
15361b807ce4Svictorle   }
1537ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A1,&v1);CHKERRQ(ierr);
1538ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A2,&v2);CHKERRQ(ierr);
153977c4ece6SBarry Smith   *flg = PETSC_TRUE;
15403a40ed3dSBarry Smith   PetscFunctionReturn(0);
1541289bc588SBarry Smith }
1542289bc588SBarry Smith 
1543e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1544289bc588SBarry Smith {
1545c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
154613f74950SBarry Smith   PetscInt          i,n,len;
1547ca15aa20SStefano Zampini   PetscScalar       *x;
1548ca15aa20SStefano Zampini   const PetscScalar *vv;
1549ca15aa20SStefano Zampini   PetscErrorCode    ierr;
155044cd7ae7SLois Curfman McInnes 
15513a40ed3dSBarry Smith   PetscFunctionBegin;
15527a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
15531ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1554d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1555ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1556e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
155744cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1558ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1559289bc588SBarry Smith   }
1560ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
15611ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
15623a40ed3dSBarry Smith   PetscFunctionReturn(0);
1563289bc588SBarry Smith }
1564289bc588SBarry Smith 
1565e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1566289bc588SBarry Smith {
1567c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1568f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1569ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1570dfbe8321SBarry Smith   PetscErrorCode    ierr;
1571d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
157255659b69SBarry Smith 
15733a40ed3dSBarry Smith   PetscFunctionBegin;
1574ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&vv);CHKERRQ(ierr);
157528988994SBarry Smith   if (ll) {
15767a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1577f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1578e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1579da3a660dSBarry Smith     for (i=0; i<m; i++) {
1580da3a660dSBarry Smith       x = l[i];
1581ca15aa20SStefano Zampini       v = vv + i;
1582b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1583da3a660dSBarry Smith     }
1584f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1585eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1586da3a660dSBarry Smith   }
158728988994SBarry Smith   if (rr) {
15887a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1589f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1590e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1591da3a660dSBarry Smith     for (i=0; i<n; i++) {
1592da3a660dSBarry Smith       x = r[i];
1593ca15aa20SStefano Zampini       v = vv + i*mat->lda;
15942205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1595da3a660dSBarry Smith     }
1596f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1597eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1598da3a660dSBarry Smith   }
1599ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&vv);CHKERRQ(ierr);
16003a40ed3dSBarry Smith   PetscFunctionReturn(0);
1601289bc588SBarry Smith }
1602289bc588SBarry Smith 
1603ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1604289bc588SBarry Smith {
1605c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1606ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1607329f5518SBarry Smith   PetscReal         sum  = 0.0;
1608d0f46423SBarry Smith   PetscInt          lda  =mat->lda,m=A->rmap->n,i,j;
1609efee365bSSatish Balay   PetscErrorCode    ierr;
161055659b69SBarry Smith 
16113a40ed3dSBarry Smith   PetscFunctionBegin;
1612ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
1613ca15aa20SStefano Zampini   v    = vv;
1614289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1615a5ce6ee0Svictorle     if (lda>m) {
1616d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1617ca15aa20SStefano Zampini         v = vv+j*lda;
1618a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1619a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1620a5ce6ee0Svictorle         }
1621a5ce6ee0Svictorle       }
1622a5ce6ee0Svictorle     } else {
1623570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1624570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1625570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1626570b7f6dSBarry Smith     }
1627570b7f6dSBarry Smith #else
1628d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1629329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1630289bc588SBarry Smith       }
1631a5ce6ee0Svictorle     }
16328f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1633570b7f6dSBarry Smith #endif
1634dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16353a40ed3dSBarry Smith   } else if (type == NORM_1) {
1636064f8208SBarry Smith     *nrm = 0.0;
1637d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1638ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
1639289bc588SBarry Smith       sum = 0.0;
1640d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
164133a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1642289bc588SBarry Smith       }
1643064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1644289bc588SBarry Smith     }
1645eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16463a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1647064f8208SBarry Smith     *nrm = 0.0;
1648d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1649ca15aa20SStefano Zampini       v   = vv + j;
1650289bc588SBarry Smith       sum = 0.0;
1651d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
16521b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1653289bc588SBarry Smith       }
1654064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1655289bc588SBarry Smith     }
1656eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1657e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
1658ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
16593a40ed3dSBarry Smith   PetscFunctionReturn(0);
1660289bc588SBarry Smith }
1661289bc588SBarry Smith 
1662e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1663289bc588SBarry Smith {
1664c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
166563ba0a88SBarry Smith   PetscErrorCode ierr;
166667e560aaSBarry Smith 
16673a40ed3dSBarry Smith   PetscFunctionBegin;
1668b5a2b587SKris Buschelman   switch (op) {
1669b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
16704e0d8c25SBarry Smith     aij->roworiented = flg;
1671b5a2b587SKris Buschelman     break;
1672512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1673b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
16743971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
16754e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
167613fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1677b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1678b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
16790f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
16805021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
1681071fcb05SBarry Smith   case MAT_SORTED_FULL:
16825021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
16835021d80fSJed Brown     break;
16845021d80fSJed Brown   case MAT_SPD:
168577e54ba9SKris Buschelman   case MAT_SYMMETRIC:
168677e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
16879a4540c5SBarry Smith   case MAT_HERMITIAN:
16889a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
16895021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
169077e54ba9SKris Buschelman     break;
1691b5a2b587SKris Buschelman   default:
1692e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
16933a40ed3dSBarry Smith   }
16943a40ed3dSBarry Smith   PetscFunctionReturn(0);
1695289bc588SBarry Smith }
1696289bc588SBarry Smith 
1697e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
16986f0a148fSBarry Smith {
1699ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
17006849ba73SBarry Smith   PetscErrorCode ierr;
1701d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
1702ca15aa20SStefano Zampini   PetscScalar    *v;
17033a40ed3dSBarry Smith 
17043a40ed3dSBarry Smith   PetscFunctionBegin;
1705ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1706a5ce6ee0Svictorle   if (lda>m) {
1707d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1708ca15aa20SStefano Zampini       ierr = PetscArrayzero(v+j*lda,m);CHKERRQ(ierr);
1709a5ce6ee0Svictorle     }
1710a5ce6ee0Svictorle   } else {
1711ca15aa20SStefano Zampini     ierr = PetscArrayzero(v,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
1712a5ce6ee0Svictorle   }
1713ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17143a40ed3dSBarry Smith   PetscFunctionReturn(0);
17156f0a148fSBarry Smith }
17166f0a148fSBarry Smith 
1717e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
17186f0a148fSBarry Smith {
171997b48c8fSBarry Smith   PetscErrorCode    ierr;
1720ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1721b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
1722ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
172397b48c8fSBarry Smith   const PetscScalar *xx;
172455659b69SBarry Smith 
17253a40ed3dSBarry Smith   PetscFunctionBegin;
172676bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1727b9679d65SBarry Smith     for (i=0; i<N; i++) {
1728b9679d65SBarry Smith       if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1729b9679d65SBarry 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);
1730b9679d65SBarry Smith     }
173176bd3646SJed Brown   }
1732ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1733b9679d65SBarry Smith 
173497b48c8fSBarry Smith   /* fix right hand side if needed */
173597b48c8fSBarry Smith   if (x && b) {
173697b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
173797b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
17382205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
173997b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
174097b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
174197b48c8fSBarry Smith   }
174297b48c8fSBarry Smith 
1743ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
17446f0a148fSBarry Smith   for (i=0; i<N; i++) {
1745ca15aa20SStefano Zampini     slot = v + rows[i];
1746b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
17476f0a148fSBarry Smith   }
1748f4df32b1SMatthew Knepley   if (diag != 0.0) {
1749b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
17506f0a148fSBarry Smith     for (i=0; i<N; i++) {
1751ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1752f4df32b1SMatthew Knepley       *slot = diag;
17536f0a148fSBarry Smith     }
17546f0a148fSBarry Smith   }
1755ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17563a40ed3dSBarry Smith   PetscFunctionReturn(0);
17576f0a148fSBarry Smith }
1758557bce09SLois Curfman McInnes 
175949a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
176049a6ff4bSBarry Smith {
176149a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
176249a6ff4bSBarry Smith 
176349a6ff4bSBarry Smith   PetscFunctionBegin;
176449a6ff4bSBarry Smith   *lda = mat->lda;
176549a6ff4bSBarry Smith   PetscFunctionReturn(0);
176649a6ff4bSBarry Smith }
176749a6ff4bSBarry Smith 
1768ca15aa20SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar *array[])
176964e87e97SBarry Smith {
1770c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
17713a40ed3dSBarry Smith 
17723a40ed3dSBarry Smith   PetscFunctionBegin;
177364e87e97SBarry Smith   *array = mat->v;
17743a40ed3dSBarry Smith   PetscFunctionReturn(0);
177564e87e97SBarry Smith }
17760754003eSLois Curfman McInnes 
1777ca15aa20SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar *array[])
1778ff14e315SSatish Balay {
17793a40ed3dSBarry Smith   PetscFunctionBegin;
17803a40ed3dSBarry Smith   PetscFunctionReturn(0);
1781ff14e315SSatish Balay }
17820754003eSLois Curfman McInnes 
1783dec5eb66SMatthew G Knepley /*@C
178449a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
178549a6ff4bSBarry Smith 
178649a6ff4bSBarry Smith    Logically Collective on Mat
178749a6ff4bSBarry Smith 
178849a6ff4bSBarry Smith    Input Parameter:
178949a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
179049a6ff4bSBarry Smith 
179149a6ff4bSBarry Smith    Output Parameter:
179249a6ff4bSBarry Smith .   lda - the leading dimension
179349a6ff4bSBarry Smith 
179449a6ff4bSBarry Smith    Level: intermediate
179549a6ff4bSBarry Smith 
179649a6ff4bSBarry Smith .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatSeqDenseSetLDA()
179749a6ff4bSBarry Smith @*/
179849a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
179949a6ff4bSBarry Smith {
180049a6ff4bSBarry Smith   PetscErrorCode ierr;
180149a6ff4bSBarry Smith 
180249a6ff4bSBarry Smith   PetscFunctionBegin;
180349a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
180449a6ff4bSBarry Smith   PetscFunctionReturn(0);
180549a6ff4bSBarry Smith }
180649a6ff4bSBarry Smith 
180749a6ff4bSBarry Smith /*@C
18088c778c55SBarry Smith    MatDenseGetArray - gives access to the array where the data for a SeqDense matrix is stored
180973a71a0fSBarry Smith 
18108572280aSBarry Smith    Logically Collective on Mat
181173a71a0fSBarry Smith 
181273a71a0fSBarry Smith    Input Parameter:
1813579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
181473a71a0fSBarry Smith 
181573a71a0fSBarry Smith    Output Parameter:
181673a71a0fSBarry Smith .   array - pointer to the data
181773a71a0fSBarry Smith 
181873a71a0fSBarry Smith    Level: intermediate
181973a71a0fSBarry Smith 
18208572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
182173a71a0fSBarry Smith @*/
18228c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
182373a71a0fSBarry Smith {
182473a71a0fSBarry Smith   PetscErrorCode ierr;
182573a71a0fSBarry Smith 
182673a71a0fSBarry Smith   PetscFunctionBegin;
18278c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
182873a71a0fSBarry Smith   PetscFunctionReturn(0);
182973a71a0fSBarry Smith }
183073a71a0fSBarry Smith 
1831dec5eb66SMatthew G Knepley /*@C
1832579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
183373a71a0fSBarry Smith 
18348572280aSBarry Smith    Logically Collective on Mat
18358572280aSBarry Smith 
18368572280aSBarry Smith    Input Parameters:
1837a2b725a8SWilliam Gropp +  mat - a MATSEQDENSE or MATMPIDENSE matrix
1838a2b725a8SWilliam Gropp -  array - pointer to the data
18398572280aSBarry Smith 
18408572280aSBarry Smith    Level: intermediate
18418572280aSBarry Smith 
18428572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
18438572280aSBarry Smith @*/
18448572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
18458572280aSBarry Smith {
18468572280aSBarry Smith   PetscErrorCode ierr;
18478572280aSBarry Smith 
18488572280aSBarry Smith   PetscFunctionBegin;
18498572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
18508572280aSBarry Smith   if (array) *array = NULL;
18518572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
18528572280aSBarry Smith   PetscFunctionReturn(0);
18538572280aSBarry Smith }
18548572280aSBarry Smith 
18558572280aSBarry Smith /*@C
18568572280aSBarry Smith    MatDenseGetArrayRead - gives access to the array where the data for a SeqDense matrix is stored
18578572280aSBarry Smith 
18588572280aSBarry Smith    Not Collective
18598572280aSBarry Smith 
18608572280aSBarry Smith    Input Parameter:
18618572280aSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
18628572280aSBarry Smith 
18638572280aSBarry Smith    Output Parameter:
18648572280aSBarry Smith .   array - pointer to the data
18658572280aSBarry Smith 
18668572280aSBarry Smith    Level: intermediate
18678572280aSBarry Smith 
18688572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArray(), MatDenseRestoreArrayRead()
18698572280aSBarry Smith @*/
18708572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
18718572280aSBarry Smith {
18728572280aSBarry Smith   PetscErrorCode ierr;
18738572280aSBarry Smith 
18748572280aSBarry Smith   PetscFunctionBegin;
18758572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
18768572280aSBarry Smith   PetscFunctionReturn(0);
18778572280aSBarry Smith }
18788572280aSBarry Smith 
18798572280aSBarry Smith /*@C
18808572280aSBarry Smith    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
18818572280aSBarry Smith 
188273a71a0fSBarry Smith    Not Collective
188373a71a0fSBarry Smith 
188473a71a0fSBarry Smith    Input Parameters:
1885a2b725a8SWilliam Gropp +  mat - a MATSEQDENSE or MATMPIDENSE matrix
1886a2b725a8SWilliam Gropp -  array - pointer to the data
188773a71a0fSBarry Smith 
188873a71a0fSBarry Smith    Level: intermediate
188973a71a0fSBarry Smith 
18908572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArray()
189173a71a0fSBarry Smith @*/
18928572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
189373a71a0fSBarry Smith {
189473a71a0fSBarry Smith   PetscErrorCode ierr;
189573a71a0fSBarry Smith 
189673a71a0fSBarry Smith   PetscFunctionBegin;
18978572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
18988572280aSBarry Smith   if (array) *array = NULL;
189973a71a0fSBarry Smith   PetscFunctionReturn(0);
190073a71a0fSBarry Smith }
190173a71a0fSBarry Smith 
19027dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
19030754003eSLois Curfman McInnes {
1904c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
19056849ba73SBarry Smith   PetscErrorCode ierr;
1906ca15aa20SStefano Zampini   PetscInt       i,j,nrows,ncols,blda;
19075d0c19d7SBarry Smith   const PetscInt *irow,*icol;
190887828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
19090754003eSLois Curfman McInnes   Mat            newmat;
19100754003eSLois Curfman McInnes 
19113a40ed3dSBarry Smith   PetscFunctionBegin;
191278b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
191378b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1914e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1915e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
19160754003eSLois Curfman McInnes 
1917182d2002SSatish Balay   /* Check submatrixcall */
1918182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
191913f74950SBarry Smith     PetscInt n_cols,n_rows;
1920182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
192121a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
1922f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
1923c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
192421a2c019SBarry Smith     }
1925182d2002SSatish Balay     newmat = *B;
1926182d2002SSatish Balay   } else {
19270754003eSLois Curfman McInnes     /* Create and fill new matrix */
1928ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
1929f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
19307adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
19310298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1932182d2002SSatish Balay   }
1933182d2002SSatish Balay 
1934182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1935ca15aa20SStefano Zampini   ierr = MatDenseGetArray(newmat,&bv);CHKERRQ(ierr);
1936ca15aa20SStefano Zampini   ierr = MatDenseGetLDA(newmat,&blda);CHKERRQ(ierr);
1937182d2002SSatish Balay   for (i=0; i<ncols; i++) {
19386de62eeeSBarry Smith     av = v + mat->lda*icol[i];
1939ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
1940ca15aa20SStefano Zampini     bv += blda;
19410754003eSLois Curfman McInnes   }
1942ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(newmat,&bv);CHKERRQ(ierr);
1943182d2002SSatish Balay 
1944182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
19456d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19466d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19470754003eSLois Curfman McInnes 
19480754003eSLois Curfman McInnes   /* Free work space */
194978b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
195078b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1951182d2002SSatish Balay   *B   = newmat;
19523a40ed3dSBarry Smith   PetscFunctionReturn(0);
19530754003eSLois Curfman McInnes }
19540754003eSLois Curfman McInnes 
19557dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1956905e6a2fSBarry Smith {
19576849ba73SBarry Smith   PetscErrorCode ierr;
195813f74950SBarry Smith   PetscInt       i;
1959905e6a2fSBarry Smith 
19603a40ed3dSBarry Smith   PetscFunctionBegin;
1961905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1962df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
1963905e6a2fSBarry Smith   }
1964905e6a2fSBarry Smith 
1965905e6a2fSBarry Smith   for (i=0; i<n; i++) {
19667dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1967905e6a2fSBarry Smith   }
19683a40ed3dSBarry Smith   PetscFunctionReturn(0);
1969905e6a2fSBarry Smith }
1970905e6a2fSBarry Smith 
1971e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
1972c0aa2d19SHong Zhang {
1973c0aa2d19SHong Zhang   PetscFunctionBegin;
1974c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1975c0aa2d19SHong Zhang }
1976c0aa2d19SHong Zhang 
1977e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
1978c0aa2d19SHong Zhang {
1979c0aa2d19SHong Zhang   PetscFunctionBegin;
1980c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1981c0aa2d19SHong Zhang }
1982c0aa2d19SHong Zhang 
1983e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
19844b0e389bSBarry Smith {
19854b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
19866849ba73SBarry Smith   PetscErrorCode    ierr;
1987ca15aa20SStefano Zampini   const PetscScalar *va;
1988ca15aa20SStefano Zampini   PetscScalar       *vb;
1989d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
19903a40ed3dSBarry Smith 
19913a40ed3dSBarry Smith   PetscFunctionBegin;
199233f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
199333f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
1994cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
19953a40ed3dSBarry Smith     PetscFunctionReturn(0);
19963a40ed3dSBarry Smith   }
1997e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
1998ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&va);CHKERRQ(ierr);
1999ca15aa20SStefano Zampini   ierr = MatDenseGetArray(B,&vb);CHKERRQ(ierr);
2000a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
20010dbb7854Svictorle     for (j=0; j<n; j++) {
2002ca15aa20SStefano Zampini       ierr = PetscArraycpy(vb+j*lda2,va+j*lda1,m);CHKERRQ(ierr);
2003a5ce6ee0Svictorle     }
2004a5ce6ee0Svictorle   } else {
2005ca15aa20SStefano Zampini     ierr = PetscArraycpy(vb,va,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2006a5ce6ee0Svictorle   }
2007ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(B,&vb);CHKERRQ(ierr);
2008ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&va);CHKERRQ(ierr);
2009ca15aa20SStefano Zampini   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2010ca15aa20SStefano Zampini   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2011273d9f13SBarry Smith   PetscFunctionReturn(0);
2012273d9f13SBarry Smith }
2013273d9f13SBarry Smith 
2014e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
2015273d9f13SBarry Smith {
2016dfbe8321SBarry Smith   PetscErrorCode ierr;
2017273d9f13SBarry Smith 
2018273d9f13SBarry Smith   PetscFunctionBegin;
2019273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
20203a40ed3dSBarry Smith   PetscFunctionReturn(0);
20214b0e389bSBarry Smith }
20224b0e389bSBarry Smith 
2023ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2024ba337c44SJed Brown {
2025ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2026ca15aa20SStefano Zampini   PetscScalar    *aa;
2027ca15aa20SStefano Zampini   PetscErrorCode ierr;
2028ba337c44SJed Brown 
2029ba337c44SJed Brown   PetscFunctionBegin;
2030ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2031ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2032ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2033ba337c44SJed Brown   PetscFunctionReturn(0);
2034ba337c44SJed Brown }
2035ba337c44SJed Brown 
2036ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2037ba337c44SJed Brown {
2038ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2039ca15aa20SStefano Zampini   PetscScalar    *aa;
2040ca15aa20SStefano Zampini   PetscErrorCode ierr;
2041ba337c44SJed Brown 
2042ba337c44SJed Brown   PetscFunctionBegin;
2043ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2044ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2045ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2046ba337c44SJed Brown   PetscFunctionReturn(0);
2047ba337c44SJed Brown }
2048ba337c44SJed Brown 
2049ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2050ba337c44SJed Brown {
2051ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2052ca15aa20SStefano Zampini   PetscScalar    *aa;
2053ca15aa20SStefano Zampini   PetscErrorCode ierr;
2054ba337c44SJed Brown 
2055ba337c44SJed Brown   PetscFunctionBegin;
2056ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2057ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
2058ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2059ba337c44SJed Brown   PetscFunctionReturn(0);
2060ba337c44SJed Brown }
2061284134d9SBarry Smith 
2062a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
20634222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2064a9fe9ddaSSatish Balay {
2065ee16a9a1SHong Zhang   PetscErrorCode ierr;
2066d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
2067ca15aa20SStefano Zampini   PetscBool      flg;
2068a9fe9ddaSSatish Balay 
2069ee16a9a1SHong Zhang   PetscFunctionBegin;
20704222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
2071ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
20724222ddf1SHong Zhang   ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
20734222ddf1SHong Zhang   ierr = MatSeqDenseSetPreallocation(C,NULL);CHKERRQ(ierr);
2074ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2075ee16a9a1SHong Zhang }
2076a9fe9ddaSSatish Balay 
2077a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2078a9fe9ddaSSatish Balay {
207952c5f739Sprj-   Mat_SeqDense       *a,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
20800805154bSBarry Smith   PetscBLASInt       m,n,k;
2081ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2082ca15aa20SStefano Zampini   PetscScalar       *cv;
2083a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2084fd4e9aacSBarry Smith   PetscBool         flg;
2085c2916339SPierre Jolivet   PetscErrorCode    (*numeric)(Mat,Mat,Mat)=NULL;
2086c2916339SPierre Jolivet   PetscErrorCode    ierr;
2087a9fe9ddaSSatish Balay 
2088a9fe9ddaSSatish Balay   PetscFunctionBegin;
2089fd4e9aacSBarry Smith   /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/
2090fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
2091c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqAIJ_SeqDense;
2092a001520aSPierre Jolivet   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQBAIJ,&flg);CHKERRQ(ierr);
2093c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqBAIJ_SeqDense;
2094c2916339SPierre Jolivet   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQSBAIJ,&flg);CHKERRQ(ierr);
2095c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqSBAIJ_SeqDense;
209652c5f739Sprj-   ierr = PetscObjectTypeCompare((PetscObject)A,MATNEST,&flg);CHKERRQ(ierr);
2097c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_Nest_Dense;
2098c2916339SPierre Jolivet   if (numeric) {
2099c2916339SPierre Jolivet     C->ops->matmultnumeric = numeric;
2100c2916339SPierre Jolivet     ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
210152c5f739Sprj-     PetscFunctionReturn(0);
210252c5f739Sprj-   }
210352c5f739Sprj-   a = (Mat_SeqDense*)A->data;
21048208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
21058208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2106c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
210749d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
2108ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
2109ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
2110ca15aa20SStefano Zampini   ierr = MatDenseGetArray(C,&cv);CHKERRQ(ierr);
2111ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
2112ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2113ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
2114ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
2115ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(C,&cv);CHKERRQ(ierr);
2116a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2117a9fe9ddaSSatish Balay }
2118a9fe9ddaSSatish Balay 
21194222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
212069f65d41SStefano Zampini {
212169f65d41SStefano Zampini   PetscErrorCode ierr;
212269f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
2123ca15aa20SStefano Zampini   PetscBool      flg;
212469f65d41SStefano Zampini 
212569f65d41SStefano Zampini   PetscFunctionBegin;
21264222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
2127ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
21284222ddf1SHong Zhang   ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
21294222ddf1SHong Zhang   ierr = MatSeqDenseSetPreallocation(C,NULL);CHKERRQ(ierr);
21304222ddf1SHong Zhang   C->ops->mattransposemultnumeric = MatMatTransposeMultNumeric_SeqDense_SeqDense;
213169f65d41SStefano Zampini   PetscFunctionReturn(0);
213269f65d41SStefano Zampini }
213369f65d41SStefano Zampini 
213469f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
213569f65d41SStefano Zampini {
213669f65d41SStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
213769f65d41SStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
213869f65d41SStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
213969f65d41SStefano Zampini   PetscBLASInt   m,n,k;
214069f65d41SStefano Zampini   PetscScalar    _DOne=1.0,_DZero=0.0;
214169f65d41SStefano Zampini   PetscErrorCode ierr;
214269f65d41SStefano Zampini 
214369f65d41SStefano Zampini   PetscFunctionBegin;
214449d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
214549d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
214669f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
214749d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
214869f65d41SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2149ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
215069f65d41SStefano Zampini   PetscFunctionReturn(0);
215169f65d41SStefano Zampini }
215269f65d41SStefano Zampini 
21534222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2154a9fe9ddaSSatish Balay {
2155ee16a9a1SHong Zhang   PetscErrorCode ierr;
2156d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
2157ca15aa20SStefano Zampini   PetscBool      flg;
2158a9fe9ddaSSatish Balay 
2159ee16a9a1SHong Zhang   PetscFunctionBegin;
21604222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
2161ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
21624222ddf1SHong Zhang   ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
21634222ddf1SHong Zhang   ierr = MatSeqDenseSetPreallocation(C,NULL);CHKERRQ(ierr);
2164ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2165ee16a9a1SHong Zhang }
2166a9fe9ddaSSatish Balay 
216775648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2168a9fe9ddaSSatish Balay {
2169a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2170a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2171a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
21720805154bSBarry Smith   PetscBLASInt   m,n,k;
2173a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
2174c5df96a5SBarry Smith   PetscErrorCode ierr;
2175a9fe9ddaSSatish Balay 
2176a9fe9ddaSSatish Balay   PetscFunctionBegin;
21778208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
21788208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2179c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
218049d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
21815ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2182ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2183a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2184a9fe9ddaSSatish Balay }
2185985db425SBarry Smith 
21864222ddf1SHong Zhang /* ----------------------------------------------- */
21874222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
21884222ddf1SHong Zhang {
21894222ddf1SHong Zhang   PetscFunctionBegin;
21904222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
21914222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
21924222ddf1SHong Zhang   /* dense mat may not call MatProductSymbolic(), thus set C->ops->productnumeric here */
21934222ddf1SHong Zhang   C->ops->productnumeric  = MatProductNumeric_AB;
21944222ddf1SHong Zhang   PetscFunctionReturn(0);
21954222ddf1SHong Zhang }
21964222ddf1SHong Zhang 
21974222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
21984222ddf1SHong Zhang {
21994222ddf1SHong Zhang   PetscFunctionBegin;
22004222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
22014222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
22024222ddf1SHong Zhang   C->ops->productnumeric           = MatProductNumeric_AtB;
22034222ddf1SHong Zhang   PetscFunctionReturn(0);
22044222ddf1SHong Zhang }
22054222ddf1SHong Zhang 
22064222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
22074222ddf1SHong Zhang {
22084222ddf1SHong Zhang   PetscFunctionBegin;
22094222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
22104222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
22114222ddf1SHong Zhang   C->ops->productnumeric           = MatProductNumeric_ABt;
22124222ddf1SHong Zhang   PetscFunctionReturn(0);
22134222ddf1SHong Zhang }
22144222ddf1SHong Zhang 
22154222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_PtAP(Mat C)
22164222ddf1SHong Zhang {
22174222ddf1SHong Zhang   PetscFunctionBegin;
22184222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_Basic;
22194222ddf1SHong Zhang   PetscFunctionReturn(0);
22204222ddf1SHong Zhang }
22214222ddf1SHong Zhang 
22224222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
22234222ddf1SHong Zhang {
22244222ddf1SHong Zhang   PetscErrorCode ierr;
22254222ddf1SHong Zhang   Mat_Product    *product = C->product;
22264222ddf1SHong Zhang 
22274222ddf1SHong Zhang   PetscFunctionBegin;
22284222ddf1SHong Zhang   switch (product->type) {
22294222ddf1SHong Zhang   case MATPRODUCT_AB:
22304222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AB(C);CHKERRQ(ierr);
22314222ddf1SHong Zhang     break;
22324222ddf1SHong Zhang   case MATPRODUCT_AtB:
22334222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AtB(C);CHKERRQ(ierr);
22344222ddf1SHong Zhang     break;
22354222ddf1SHong Zhang   case MATPRODUCT_ABt:
22364222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_ABt(C);CHKERRQ(ierr);
22374222ddf1SHong Zhang     break;
22384222ddf1SHong Zhang   case MATPRODUCT_PtAP:
22394222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_PtAP(C);CHKERRQ(ierr);
22404222ddf1SHong Zhang     break;
2241544a5e07SHong Zhang   default: SETERRQ1(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProduct type %s is not supported for SeqDense and SeqDense matrices",MatProductTypes[product->type]);
22424222ddf1SHong Zhang   }
22434222ddf1SHong Zhang   PetscFunctionReturn(0);
22444222ddf1SHong Zhang }
22454222ddf1SHong Zhang /* ----------------------------------------------- */
22464222ddf1SHong Zhang 
2247e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2248985db425SBarry Smith {
2249985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2250985db425SBarry Smith   PetscErrorCode     ierr;
2251d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2252985db425SBarry Smith   PetscScalar        *x;
2253ca15aa20SStefano Zampini   const PetscScalar *aa;
2254985db425SBarry Smith 
2255985db425SBarry Smith   PetscFunctionBegin;
2256e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2257985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2258985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2259ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2260e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2261985db425SBarry Smith   for (i=0; i<m; i++) {
2262985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2263985db425SBarry Smith     for (j=1; j<n; j++) {
2264ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2265985db425SBarry Smith     }
2266985db425SBarry Smith   }
2267ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2268985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2269985db425SBarry Smith   PetscFunctionReturn(0);
2270985db425SBarry Smith }
2271985db425SBarry Smith 
2272e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2273985db425SBarry Smith {
2274985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2275985db425SBarry Smith   PetscErrorCode    ierr;
2276d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2277985db425SBarry Smith   PetscScalar       *x;
2278985db425SBarry Smith   PetscReal         atmp;
2279ca15aa20SStefano Zampini   const PetscScalar *aa;
2280985db425SBarry Smith 
2281985db425SBarry Smith   PetscFunctionBegin;
2282e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2283985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2284985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2285ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2286e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2287985db425SBarry Smith   for (i=0; i<m; i++) {
22889189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2289985db425SBarry Smith     for (j=1; j<n; j++) {
2290ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2291985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2292985db425SBarry Smith     }
2293985db425SBarry Smith   }
2294ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2295985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2296985db425SBarry Smith   PetscFunctionReturn(0);
2297985db425SBarry Smith }
2298985db425SBarry Smith 
2299e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2300985db425SBarry Smith {
2301985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2302985db425SBarry Smith   PetscErrorCode    ierr;
2303d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2304985db425SBarry Smith   PetscScalar       *x;
2305ca15aa20SStefano Zampini   const PetscScalar *aa;
2306985db425SBarry Smith 
2307985db425SBarry Smith   PetscFunctionBegin;
2308e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2309ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2310985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2311985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2312e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2313985db425SBarry Smith   for (i=0; i<m; i++) {
2314985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2315985db425SBarry Smith     for (j=1; j<n; j++) {
2316ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2317985db425SBarry Smith     }
2318985db425SBarry Smith   }
2319985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2320ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2321985db425SBarry Smith   PetscFunctionReturn(0);
2322985db425SBarry Smith }
2323985db425SBarry Smith 
2324e0877f53SBarry Smith static PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
23258d0534beSBarry Smith {
23268d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
23278d0534beSBarry Smith   PetscErrorCode    ierr;
23288d0534beSBarry Smith   PetscScalar       *x;
2329ca15aa20SStefano Zampini   const PetscScalar *aa;
23308d0534beSBarry Smith 
23318d0534beSBarry Smith   PetscFunctionBegin;
2332e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2333ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
23348d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2335ca15aa20SStefano Zampini   ierr = PetscArraycpy(x,aa+col*a->lda,A->rmap->n);CHKERRQ(ierr);
23368d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2337ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
23388d0534beSBarry Smith   PetscFunctionReturn(0);
23398d0534beSBarry Smith }
23408d0534beSBarry Smith 
234152c5f739Sprj- PETSC_INTERN PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
23420716a85fSBarry Smith {
23430716a85fSBarry Smith   PetscErrorCode    ierr;
23440716a85fSBarry Smith   PetscInt          i,j,m,n;
23451683a169SBarry Smith   const PetscScalar *a;
23460716a85fSBarry Smith 
23470716a85fSBarry Smith   PetscFunctionBegin;
23480716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2349580bdb30SBarry Smith   ierr = PetscArrayzero(norms,n);CHKERRQ(ierr);
23501683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&a);CHKERRQ(ierr);
23510716a85fSBarry Smith   if (type == NORM_2) {
23520716a85fSBarry Smith     for (i=0; i<n; i++) {
23530716a85fSBarry Smith       for (j=0; j<m; j++) {
23540716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
23550716a85fSBarry Smith       }
23560716a85fSBarry Smith       a += m;
23570716a85fSBarry Smith     }
23580716a85fSBarry Smith   } else if (type == NORM_1) {
23590716a85fSBarry Smith     for (i=0; i<n; i++) {
23600716a85fSBarry Smith       for (j=0; j<m; j++) {
23610716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
23620716a85fSBarry Smith       }
23630716a85fSBarry Smith       a += m;
23640716a85fSBarry Smith     }
23650716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
23660716a85fSBarry Smith     for (i=0; i<n; i++) {
23670716a85fSBarry Smith       for (j=0; j<m; j++) {
23680716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
23690716a85fSBarry Smith       }
23700716a85fSBarry Smith       a += m;
23710716a85fSBarry Smith     }
2372ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
23731683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&a);CHKERRQ(ierr);
23740716a85fSBarry Smith   if (type == NORM_2) {
23758f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
23760716a85fSBarry Smith   }
23770716a85fSBarry Smith   PetscFunctionReturn(0);
23780716a85fSBarry Smith }
23790716a85fSBarry Smith 
238073a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
238173a71a0fSBarry Smith {
238273a71a0fSBarry Smith   PetscErrorCode ierr;
238373a71a0fSBarry Smith   PetscScalar    *a;
238473a71a0fSBarry Smith   PetscInt       m,n,i;
238573a71a0fSBarry Smith 
238673a71a0fSBarry Smith   PetscFunctionBegin;
238773a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
23888c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
238973a71a0fSBarry Smith   for (i=0; i<m*n; i++) {
239073a71a0fSBarry Smith     ierr = PetscRandomGetValue(rctx,a+i);CHKERRQ(ierr);
239173a71a0fSBarry Smith   }
23928c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
239373a71a0fSBarry Smith   PetscFunctionReturn(0);
239473a71a0fSBarry Smith }
239573a71a0fSBarry Smith 
23963b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
23973b49f96aSBarry Smith {
23983b49f96aSBarry Smith   PetscFunctionBegin;
23993b49f96aSBarry Smith   *missing = PETSC_FALSE;
24003b49f96aSBarry Smith   PetscFunctionReturn(0);
24013b49f96aSBarry Smith }
240273a71a0fSBarry Smith 
2403ca15aa20SStefano Zampini /* vals is not const */
2404af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
240586aefd0dSHong Zhang {
2406ca15aa20SStefano Zampini   PetscErrorCode ierr;
240786aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2408ca15aa20SStefano Zampini   PetscScalar    *v;
240986aefd0dSHong Zhang 
241086aefd0dSHong Zhang   PetscFunctionBegin;
241186aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2412ca15aa20SStefano Zampini   ierr  = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2413ca15aa20SStefano Zampini   *vals = v+col*a->lda;
2414ca15aa20SStefano Zampini   ierr  = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
241586aefd0dSHong Zhang   PetscFunctionReturn(0);
241686aefd0dSHong Zhang }
241786aefd0dSHong Zhang 
2418af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
241986aefd0dSHong Zhang {
242086aefd0dSHong Zhang   PetscFunctionBegin;
242186aefd0dSHong Zhang   *vals = 0; /* user cannot accidently use the array later */
242286aefd0dSHong Zhang   PetscFunctionReturn(0);
242386aefd0dSHong Zhang }
2424abc3b08eSStefano Zampini 
2425289bc588SBarry Smith /* -------------------------------------------------------------------*/
2426a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2427905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2428905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2429905e6a2fSBarry Smith                                         MatMult_SeqDense,
243097304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
24317c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
24327c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2433db4efbfdSBarry Smith                                         0,
2434db4efbfdSBarry Smith                                         0,
2435db4efbfdSBarry Smith                                         0,
2436db4efbfdSBarry Smith                                 /* 10*/ 0,
2437905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2438905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
243941f059aeSBarry Smith                                         MatSOR_SeqDense,
2440ec8511deSBarry Smith                                         MatTranspose_SeqDense,
244197304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2442905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2443905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2444905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2445905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2446c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2447c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2448905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2449905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2450d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2451db4efbfdSBarry Smith                                         0,
2452db4efbfdSBarry Smith                                         0,
2453db4efbfdSBarry Smith                                         0,
2454db4efbfdSBarry Smith                                         0,
24554994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2456273d9f13SBarry Smith                                         0,
2457905e6a2fSBarry Smith                                         0,
245873a71a0fSBarry Smith                                         0,
245973a71a0fSBarry Smith                                         0,
2460d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2461a5ae1ecdSBarry Smith                                         0,
2462a5ae1ecdSBarry Smith                                         0,
2463a5ae1ecdSBarry Smith                                         0,
2464a5ae1ecdSBarry Smith                                         0,
2465d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
24667dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2467a5ae1ecdSBarry Smith                                         0,
24684b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2469a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2470d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2471a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
24727d68702bSBarry Smith                                         MatShift_Basic,
2473a5ae1ecdSBarry Smith                                         0,
24743f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
247573a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2476a5ae1ecdSBarry Smith                                         0,
2477a5ae1ecdSBarry Smith                                         0,
2478a5ae1ecdSBarry Smith                                         0,
2479a5ae1ecdSBarry Smith                                         0,
2480d519adbfSMatthew Knepley                                 /* 54*/ 0,
2481a5ae1ecdSBarry Smith                                         0,
2482a5ae1ecdSBarry Smith                                         0,
2483a5ae1ecdSBarry Smith                                         0,
2484a5ae1ecdSBarry Smith                                         0,
2485d519adbfSMatthew Knepley                                 /* 59*/ 0,
2486e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2487e03a110bSBarry Smith                                         MatView_SeqDense,
2488357abbc8SBarry Smith                                         0,
248997304618SKris Buschelman                                         0,
2490d519adbfSMatthew Knepley                                 /* 64*/ 0,
249197304618SKris Buschelman                                         0,
249297304618SKris Buschelman                                         0,
249397304618SKris Buschelman                                         0,
249497304618SKris Buschelman                                         0,
2495d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
249697304618SKris Buschelman                                         0,
249797304618SKris Buschelman                                         0,
249897304618SKris Buschelman                                         0,
249997304618SKris Buschelman                                         0,
2500d519adbfSMatthew Knepley                                 /* 74*/ 0,
250197304618SKris Buschelman                                         0,
250297304618SKris Buschelman                                         0,
250397304618SKris Buschelman                                         0,
250497304618SKris Buschelman                                         0,
2505d519adbfSMatthew Knepley                                 /* 79*/ 0,
250697304618SKris Buschelman                                         0,
250797304618SKris Buschelman                                         0,
250897304618SKris Buschelman                                         0,
25095bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2510865e5f61SKris Buschelman                                         0,
25111cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2512865e5f61SKris Buschelman                                         0,
2513865e5f61SKris Buschelman                                         0,
2514865e5f61SKris Buschelman                                         0,
25154222ddf1SHong Zhang                                 /* 89*/ 0,
25164222ddf1SHong Zhang                                         0,
2517a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
25184222ddf1SHong Zhang                                         0,
25194222ddf1SHong Zhang                                         0,
25204222ddf1SHong Zhang                                 /* 94*/ 0,
25214222ddf1SHong Zhang                                         0,
25224222ddf1SHong Zhang                                         0,
252369f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2524284134d9SBarry Smith                                         0,
25254222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
2526284134d9SBarry Smith                                         0,
2527284134d9SBarry Smith                                         0,
2528ba337c44SJed Brown                                         MatConjugate_SeqDense,
2529f73d5cc4SBarry Smith                                         0,
2530ba337c44SJed Brown                                 /*104*/ 0,
2531ba337c44SJed Brown                                         MatRealPart_SeqDense,
2532ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2533985db425SBarry Smith                                         0,
2534985db425SBarry Smith                                         0,
25358208b9aeSStefano Zampini                                 /*109*/ 0,
2536985db425SBarry Smith                                         0,
25378d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2538aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
25393b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2540aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2541aabbc4fbSShri Abhyankar                                         0,
2542aabbc4fbSShri Abhyankar                                         0,
2543aabbc4fbSShri Abhyankar                                         0,
2544aabbc4fbSShri Abhyankar                                         0,
2545aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2546aabbc4fbSShri Abhyankar                                         0,
2547aabbc4fbSShri Abhyankar                                         0,
25480716a85fSBarry Smith                                         0,
25490716a85fSBarry Smith                                         0,
25500716a85fSBarry Smith                                 /*124*/ 0,
25515df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
25525df89d91SHong Zhang                                         0,
25535df89d91SHong Zhang                                         0,
25545df89d91SHong Zhang                                         0,
25555df89d91SHong Zhang                                 /*129*/ 0,
25564222ddf1SHong Zhang                                         0,
25574222ddf1SHong Zhang                                         0,
255875648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
25593964eb88SJed Brown                                         0,
25603964eb88SJed Brown                                 /*134*/ 0,
25613964eb88SJed Brown                                         0,
25623964eb88SJed Brown                                         0,
25633964eb88SJed Brown                                         0,
25643964eb88SJed Brown                                         0,
25653964eb88SJed Brown                                 /*139*/ 0,
2566f9426fe0SMark Adams                                         0,
2567d528f656SJakub Kruzik                                         0,
2568d528f656SJakub Kruzik                                         0,
2569d528f656SJakub Kruzik                                         0,
25704222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
25714222ddf1SHong Zhang                                 /*145*/ 0,
25724222ddf1SHong Zhang                                         0,
25734222ddf1SHong Zhang                                         0
2574985db425SBarry Smith };
257590ace30eSBarry Smith 
25764b828684SBarry Smith /*@C
2577fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2578d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2579d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2580289bc588SBarry Smith 
2581d083f849SBarry Smith    Collective
2582db81eaa0SLois Curfman McInnes 
258320563c6bSBarry Smith    Input Parameters:
2584db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
25850c775827SLois Curfman McInnes .  m - number of rows
258618f449edSLois Curfman McInnes .  n - number of columns
25870298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2588dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
258920563c6bSBarry Smith 
259020563c6bSBarry Smith    Output Parameter:
259144cd7ae7SLois Curfman McInnes .  A - the matrix
259220563c6bSBarry Smith 
2593b259b22eSLois Curfman McInnes    Notes:
259418f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
259518f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
25960298fd71SBarry Smith    set data=NULL.
259718f449edSLois Curfman McInnes 
2598027ccd11SLois Curfman McInnes    Level: intermediate
2599027ccd11SLois Curfman McInnes 
260069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
260120563c6bSBarry Smith @*/
26027087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2603289bc588SBarry Smith {
2604dfbe8321SBarry Smith   PetscErrorCode ierr;
26053b2fbd54SBarry Smith 
26063a40ed3dSBarry Smith   PetscFunctionBegin;
2607f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2608f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2609273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2610273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2611273d9f13SBarry Smith   PetscFunctionReturn(0);
2612273d9f13SBarry Smith }
2613273d9f13SBarry Smith 
2614273d9f13SBarry Smith /*@C
2615273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2616273d9f13SBarry Smith 
2617d083f849SBarry Smith    Collective
2618273d9f13SBarry Smith 
2619273d9f13SBarry Smith    Input Parameters:
26201c4f3114SJed Brown +  B - the matrix
26210298fd71SBarry Smith -  data - the array (or NULL)
2622273d9f13SBarry Smith 
2623273d9f13SBarry Smith    Notes:
2624273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2625273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2626284134d9SBarry Smith    need not call this routine.
2627273d9f13SBarry Smith 
2628273d9f13SBarry Smith    Level: intermediate
2629273d9f13SBarry Smith 
263069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA()
2631867c911aSBarry Smith 
2632273d9f13SBarry Smith @*/
26337087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2634273d9f13SBarry Smith {
26354ac538c5SBarry Smith   PetscErrorCode ierr;
2636a23d5eceSKris Buschelman 
2637a23d5eceSKris Buschelman   PetscFunctionBegin;
26384ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2639a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2640a23d5eceSKris Buschelman }
2641a23d5eceSKris Buschelman 
26427087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2643a23d5eceSKris Buschelman {
2644273d9f13SBarry Smith   Mat_SeqDense   *b;
2645dfbe8321SBarry Smith   PetscErrorCode ierr;
2646273d9f13SBarry Smith 
2647273d9f13SBarry Smith   PetscFunctionBegin;
2648273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2649a868139aSShri Abhyankar 
265034ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
265134ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
265234ef9618SShri Abhyankar 
2653273d9f13SBarry Smith   b       = (Mat_SeqDense*)B->data;
265486d161a7SShri Abhyankar   b->Mmax = B->rmap->n;
265586d161a7SShri Abhyankar   b->Nmax = B->cmap->n;
265686d161a7SShri Abhyankar   if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n;
265786d161a7SShri Abhyankar 
2658220afb94SBarry Smith   ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr);
26599e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
26609e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2661e92229d0SSatish Balay     ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr);
26623bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
26632205254eSKarl Rupp 
26649e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2665273d9f13SBarry Smith   } else { /* user-allocated storage */
26669e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2667273d9f13SBarry Smith     b->v          = data;
2668273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2669273d9f13SBarry Smith   }
26700450473dSBarry Smith   B->assembled = PETSC_TRUE;
2671273d9f13SBarry Smith   PetscFunctionReturn(0);
2672273d9f13SBarry Smith }
2673273d9f13SBarry Smith 
267465b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2675cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
26768baccfbdSHong Zhang {
2677d77f618aSHong Zhang   Mat               mat_elemental;
2678d77f618aSHong Zhang   PetscErrorCode    ierr;
26791683a169SBarry Smith   const PetscScalar *array;
26801683a169SBarry Smith   PetscScalar       *v_colwise;
2681d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2682d77f618aSHong Zhang 
26838baccfbdSHong Zhang   PetscFunctionBegin;
2684d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
26851683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&array);CHKERRQ(ierr);
2686d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2687d77f618aSHong Zhang   k = 0;
2688d77f618aSHong Zhang   for (j=0; j<N; j++) {
2689d77f618aSHong Zhang     cols[j] = j;
2690d77f618aSHong Zhang     for (i=0; i<M; i++) {
2691d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2692d77f618aSHong Zhang     }
2693d77f618aSHong Zhang   }
2694d77f618aSHong Zhang   for (i=0; i<M; i++) {
2695d77f618aSHong Zhang     rows[i] = i;
2696d77f618aSHong Zhang   }
26971683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&array);CHKERRQ(ierr);
2698d77f618aSHong Zhang 
2699d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2700d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2701d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2702d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2703d77f618aSHong Zhang 
2704d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2705d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2706d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2707d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2708d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2709d77f618aSHong Zhang 
2710511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
271128be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2712d77f618aSHong Zhang   } else {
2713d77f618aSHong Zhang     *newmat = mat_elemental;
2714d77f618aSHong Zhang   }
27158baccfbdSHong Zhang   PetscFunctionReturn(0);
27168baccfbdSHong Zhang }
271765b80a83SHong Zhang #endif
27188baccfbdSHong Zhang 
27191b807ce4Svictorle /*@C
27201b807ce4Svictorle   MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array
27211b807ce4Svictorle 
27221b807ce4Svictorle   Input parameter:
27231b807ce4Svictorle + A - the matrix
27241b807ce4Svictorle - lda - the leading dimension
27251b807ce4Svictorle 
27261b807ce4Svictorle   Notes:
2727867c911aSBarry Smith   This routine is to be used in conjunction with MatSeqDenseSetPreallocation();
27281b807ce4Svictorle   it asserts that the preallocation has a leading dimension (the LDA parameter
27291b807ce4Svictorle   of Blas and Lapack fame) larger than M, the first dimension of the matrix.
27301b807ce4Svictorle 
27311b807ce4Svictorle   Level: intermediate
27321b807ce4Svictorle 
2733284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize()
2734867c911aSBarry Smith 
27351b807ce4Svictorle @*/
27367087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetLDA(Mat B,PetscInt lda)
27371b807ce4Svictorle {
27381b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
273921a2c019SBarry Smith 
27401b807ce4Svictorle   PetscFunctionBegin;
2741e32f2f54SBarry 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);
27421b807ce4Svictorle   b->lda       = lda;
274321a2c019SBarry Smith   b->changelda = PETSC_FALSE;
274421a2c019SBarry Smith   b->Mmax      = PetscMax(b->Mmax,lda);
27451b807ce4Svictorle   PetscFunctionReturn(0);
27461b807ce4Svictorle }
27471b807ce4Svictorle 
2748d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
2749d528f656SJakub Kruzik {
2750d528f656SJakub Kruzik   PetscErrorCode ierr;
2751d528f656SJakub Kruzik   PetscMPIInt    size;
2752d528f656SJakub Kruzik 
2753d528f656SJakub Kruzik   PetscFunctionBegin;
2754d528f656SJakub Kruzik   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2755d528f656SJakub Kruzik   if (size == 1) {
2756d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
2757d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
2758d528f656SJakub Kruzik     } else {
2759d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2760d528f656SJakub Kruzik     }
2761d528f656SJakub Kruzik   } else {
2762d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
2763d528f656SJakub Kruzik   }
2764d528f656SJakub Kruzik   PetscFunctionReturn(0);
2765d528f656SJakub Kruzik }
2766d528f656SJakub Kruzik 
27670bad9183SKris Buschelman /*MC
2768fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
27690bad9183SKris Buschelman 
27700bad9183SKris Buschelman    Options Database Keys:
27710bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
27720bad9183SKris Buschelman 
27730bad9183SKris Buschelman   Level: beginner
27740bad9183SKris Buschelman 
277589665df3SBarry Smith .seealso: MatCreateSeqDense()
277689665df3SBarry Smith 
27770bad9183SKris Buschelman M*/
2778ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
2779273d9f13SBarry Smith {
2780273d9f13SBarry Smith   Mat_SeqDense   *b;
2781dfbe8321SBarry Smith   PetscErrorCode ierr;
27827c334f02SBarry Smith   PetscMPIInt    size;
2783273d9f13SBarry Smith 
2784273d9f13SBarry Smith   PetscFunctionBegin;
2785ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
2786e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
278755659b69SBarry Smith 
2788b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
2789549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
279044cd7ae7SLois Curfman McInnes   B->data = (void*)b;
279118f449edSLois Curfman McInnes 
2792273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
27934e220ebcSLois Curfman McInnes 
279449a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
2795bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
27968572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2797d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
2798d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
27998572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2800715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2801bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
28028baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
28038baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
28048baccfbdSHong Zhang #endif
28052bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
28062bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA);CHKERRQ(ierr);
28074222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
28084222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
28094222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaijcusparse_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
28102bf066beSStefano Zampini #endif
2811bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
28124222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
28134222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
2814bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2815bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
28164222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
2817a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqbaij_seqdense_C",MatMatMultSymbolic_SeqBAIJ_SeqDense);CHKERRQ(ierr);
2818a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqbaij_seqdense_C",MatMatMultNumeric_SeqBAIJ_SeqDense);CHKERRQ(ierr);
28194222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
2820c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqsbaij_seqdense_C",MatMatMultSymbolic_SeqSBAIJ_SeqDense);CHKERRQ(ierr);
2821c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqsbaij_seqdense_C",MatMatMultNumeric_SeqSBAIJ_SeqDense);CHKERRQ(ierr);
28224099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijperm_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28234099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijperm_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2824e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijsell_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2825e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijsell_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
282696e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijmkl_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
282796e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijmkl_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
282852c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_nest_seqdense_C",MatMatMultSymbolic_Nest_Dense);CHKERRQ(ierr);
282952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_nest_seqdense_C",MatMatMultNumeric_Nest_Dense);CHKERRQ(ierr);
283096e6d5c4SRichard Tran Mills 
28313bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28323bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
28334099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28344099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2835e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2836e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
283796e6d5c4SRichard Tran Mills 
283896e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
283996e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2840af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
2841af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
284217667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
28433a40ed3dSBarry Smith   PetscFunctionReturn(0);
2844289bc588SBarry Smith }
284586aefd0dSHong Zhang 
284686aefd0dSHong Zhang /*@C
2847af53bab2SHong 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.
284886aefd0dSHong Zhang 
284986aefd0dSHong Zhang    Not Collective
285086aefd0dSHong Zhang 
285186aefd0dSHong Zhang    Input Parameter:
285286aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
285386aefd0dSHong Zhang -  col - column index
285486aefd0dSHong Zhang 
285586aefd0dSHong Zhang    Output Parameter:
285686aefd0dSHong Zhang .  vals - pointer to the data
285786aefd0dSHong Zhang 
285886aefd0dSHong Zhang    Level: intermediate
285986aefd0dSHong Zhang 
286086aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
286186aefd0dSHong Zhang @*/
286286aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
286386aefd0dSHong Zhang {
286486aefd0dSHong Zhang   PetscErrorCode ierr;
286586aefd0dSHong Zhang 
286686aefd0dSHong Zhang   PetscFunctionBegin;
286786aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
286886aefd0dSHong Zhang   PetscFunctionReturn(0);
286986aefd0dSHong Zhang }
287086aefd0dSHong Zhang 
287186aefd0dSHong Zhang /*@C
287286aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
287386aefd0dSHong Zhang 
287486aefd0dSHong Zhang    Not Collective
287586aefd0dSHong Zhang 
287686aefd0dSHong Zhang    Input Parameter:
287786aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
287886aefd0dSHong Zhang 
287986aefd0dSHong Zhang    Output Parameter:
288086aefd0dSHong Zhang .  vals - pointer to the data
288186aefd0dSHong Zhang 
288286aefd0dSHong Zhang    Level: intermediate
288386aefd0dSHong Zhang 
288486aefd0dSHong Zhang .seealso: MatDenseGetColumn()
288586aefd0dSHong Zhang @*/
288686aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
288786aefd0dSHong Zhang {
288886aefd0dSHong Zhang   PetscErrorCode ierr;
288986aefd0dSHong Zhang 
289086aefd0dSHong Zhang   PetscFunctionBegin;
289186aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
289286aefd0dSHong Zhang   PetscFunctionReturn(0);
289386aefd0dSHong Zhang }
2894