xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 637a00707ce14f5a4938f90425bc854823738873)
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 
316*637a0070SStefano Zampini 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++) {
353*637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) {
354*637a0070SStefano Zampini         goto restore;
3551cbb95d3SBarry Smith       }
3561cbb95d3SBarry Smith     }
357*637a0070SStefano Zampini   }
3581cbb95d3SBarry Smith   *fl  = PETSC_TRUE;
359*637a0070SStefano Zampini restore:
360*637a0070SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
361*637a0070SStefano Zampini   PetscFunctionReturn(0);
362*637a0070SStefano Zampini }
363*637a0070SStefano Zampini 
364*637a0070SStefano Zampini static PetscErrorCode MatIsSymmetric_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
365*637a0070SStefano Zampini {
366*637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
367*637a0070SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
368*637a0070SStefano Zampini   const PetscScalar *v;
369*637a0070SStefano Zampini   PetscErrorCode    ierr;
370*637a0070SStefano Zampini 
371*637a0070SStefano Zampini   PetscFunctionBegin;
372*637a0070SStefano Zampini   *fl = PETSC_FALSE;
373*637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
374*637a0070SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
375*637a0070SStefano Zampini   for (i=0; i<m; i++) {
376*637a0070SStefano Zampini     for (j=i; j<m; j++) {
377*637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - v[j+i*N]) > rtol) {
378*637a0070SStefano Zampini         goto restore;
379*637a0070SStefano Zampini       }
380*637a0070SStefano Zampini     }
381*637a0070SStefano Zampini   }
382*637a0070SStefano Zampini   *fl  = PETSC_TRUE;
383*637a0070SStefano Zampini restore:
384*637a0070SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
3851cbb95d3SBarry Smith   PetscFunctionReturn(0);
3861cbb95d3SBarry Smith }
3871cbb95d3SBarry Smith 
388ca15aa20SStefano Zampini PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
389b24902e0SBarry Smith {
390ca15aa20SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
391b24902e0SBarry Smith   PetscErrorCode ierr;
392b24902e0SBarry Smith   PetscInt       lda = (PetscInt)mat->lda,j,m;
393b24902e0SBarry Smith 
394b24902e0SBarry Smith   PetscFunctionBegin;
395aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr);
396aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr);
3970298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr);
398b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
399ca15aa20SStefano Zampini     const PetscScalar *av;
400ca15aa20SStefano Zampini     PetscScalar       *v;
401ca15aa20SStefano Zampini 
402ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
403ca15aa20SStefano Zampini     ierr = MatDenseGetArray(newi,&v);CHKERRQ(ierr);
404d0f46423SBarry Smith     if (lda>A->rmap->n) {
405d0f46423SBarry Smith       m = A->rmap->n;
406d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
407ca15aa20SStefano Zampini         ierr = PetscArraycpy(v+j*m,av+j*lda,m);CHKERRQ(ierr);
408b24902e0SBarry Smith       }
409b24902e0SBarry Smith     } else {
410ca15aa20SStefano Zampini       ierr = PetscArraycpy(v,av,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
411b24902e0SBarry Smith     }
412ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(newi,&v);CHKERRQ(ierr);
413ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
414b24902e0SBarry Smith   }
415b24902e0SBarry Smith   PetscFunctionReturn(0);
416b24902e0SBarry Smith }
417b24902e0SBarry Smith 
418ca15aa20SStefano Zampini PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
41902cad45dSBarry Smith {
4206849ba73SBarry Smith   PetscErrorCode ierr;
42102cad45dSBarry Smith 
4223a40ed3dSBarry Smith   PetscFunctionBegin;
423ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr);
424d0f46423SBarry Smith   ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4255c9eb25fSBarry Smith   ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
426719d5645SBarry Smith   ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr);
427b24902e0SBarry Smith   PetscFunctionReturn(0);
428b24902e0SBarry Smith }
429b24902e0SBarry Smith 
430e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
431289bc588SBarry Smith {
4324482741eSBarry Smith   MatFactorInfo  info;
433a093e273SMatthew Knepley   PetscErrorCode ierr;
4343a40ed3dSBarry Smith 
4353a40ed3dSBarry Smith   PetscFunctionBegin;
436c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
437ca15aa20SStefano Zampini   ierr = (*fact->ops->lufactor)(fact,0,0,&info);CHKERRQ(ierr);
4383a40ed3dSBarry Smith   PetscFunctionReturn(0);
439289bc588SBarry Smith }
4406ee01492SSatish Balay 
441e0877f53SBarry Smith static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy)
442289bc588SBarry Smith {
443c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
4446849ba73SBarry Smith   PetscErrorCode    ierr;
445f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
446f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
447c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
44867e560aaSBarry Smith 
4493a40ed3dSBarry Smith   PetscFunctionBegin;
450c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
451f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4521ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
453580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
454d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_LU) {
45500121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4568b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
45700121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
458e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
459d5f3da31SBarry Smith   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
460a49dc2a2SStefano Zampini     if (A->spd) {
46100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4628b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
46300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
464e32f2f54SBarry Smith       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
465a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
466a49dc2a2SStefano Zampini     } else if (A->hermitian) {
46700121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
468a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
46900121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
470a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
471a49dc2a2SStefano Zampini #endif
472a49dc2a2SStefano Zampini     } else { /* symmetric case */
47300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
474a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
47500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
476a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
477a49dc2a2SStefano Zampini     }
4782205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
479f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4801ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
481dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
4823a40ed3dSBarry Smith   PetscFunctionReturn(0);
483289bc588SBarry Smith }
4846ee01492SSatish Balay 
485e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X)
48685e2c93fSHong Zhang {
48785e2c93fSHong Zhang   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
48885e2c93fSHong Zhang   PetscErrorCode    ierr;
4891683a169SBarry Smith   const PetscScalar *b;
4901683a169SBarry Smith   PetscScalar       *x;
491efb80c78SLisandro Dalcin   PetscInt          n;
492783b601eSJed Brown   PetscBLASInt      nrhs,info,m;
49385e2c93fSHong Zhang 
49485e2c93fSHong Zhang   PetscFunctionBegin;
495c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
4960298fd71SBarry Smith   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
497c5df96a5SBarry Smith   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
4981683a169SBarry Smith   ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
4998c778c55SBarry Smith   ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr);
50085e2c93fSHong Zhang 
501580bdb30SBarry Smith   ierr = PetscArraycpy(x,b,m*nrhs);CHKERRQ(ierr);
50285e2c93fSHong Zhang 
50385e2c93fSHong Zhang   if (A->factortype == MAT_FACTOR_LU) {
50400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5058b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
50600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
50785e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
50885e2c93fSHong Zhang   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
509a49dc2a2SStefano Zampini     if (A->spd) {
51000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5118b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
51200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
51385e2c93fSHong Zhang       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
514a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
515a49dc2a2SStefano Zampini     } else if (A->hermitian) {
51600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
517a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
51800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
519a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
520a49dc2a2SStefano Zampini #endif
521a49dc2a2SStefano Zampini     } else { /* symmetric case */
52200121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
523a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
52400121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
525a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
526a49dc2a2SStefano Zampini     }
5272205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
52885e2c93fSHong Zhang 
5291683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
5308c778c55SBarry Smith   ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr);
53185e2c93fSHong Zhang   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
53285e2c93fSHong Zhang   PetscFunctionReturn(0);
53385e2c93fSHong Zhang }
53485e2c93fSHong Zhang 
53500121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
53600121966SStefano Zampini 
537e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
538da3a660dSBarry Smith {
539c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
540dfbe8321SBarry Smith   PetscErrorCode    ierr;
541f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
542f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
543c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
54467e560aaSBarry Smith 
5453a40ed3dSBarry Smith   PetscFunctionBegin;
546c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
547f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5481ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
549580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
5508208b9aeSStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
55100121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5528b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
55300121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
554e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve");
5558208b9aeSStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
556a49dc2a2SStefano Zampini     if (A->spd) {
55700121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
55800121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
55900121966SStefano Zampini #endif
56000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5618b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
56200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
56300121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
56400121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
56500121966SStefano Zampini #endif
566a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
567a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
568a49dc2a2SStefano Zampini     } else if (A->hermitian) {
56900121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
57000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
57100121966SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
57200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
57300121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
574ae7cfcebSSatish Balay #endif
575a49dc2a2SStefano Zampini     } else { /* symmetric case */
57600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
577a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
57800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
579a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
580da3a660dSBarry Smith     }
581a49dc2a2SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
582f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5831ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
584dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
5853a40ed3dSBarry Smith   PetscFunctionReturn(0);
586da3a660dSBarry Smith }
5876ee01492SSatish Balay 
588db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
589db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
590db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
591ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
592db4efbfdSBarry Smith {
593db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
594db4efbfdSBarry Smith   PetscErrorCode ierr;
595db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
596db4efbfdSBarry Smith 
597db4efbfdSBarry Smith   PetscFunctionBegin;
598c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
599c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
600db4efbfdSBarry Smith   if (!mat->pivots) {
6018208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
6023bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
603db4efbfdSBarry Smith   }
604db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
6058e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6068b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
6078e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
6088e57ea43SSatish Balay 
609e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
610e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
6118208b9aeSStefano Zampini 
612db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6138208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
614db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
615d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
616db4efbfdSBarry Smith 
617f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
618f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
619f6224b95SHong Zhang 
620dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
621db4efbfdSBarry Smith   PetscFunctionReturn(0);
622db4efbfdSBarry Smith }
623db4efbfdSBarry Smith 
624a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
625ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
626db4efbfdSBarry Smith {
627db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
628db4efbfdSBarry Smith   PetscErrorCode ierr;
629c5df96a5SBarry Smith   PetscBLASInt   info,n;
630db4efbfdSBarry Smith 
631db4efbfdSBarry Smith   PetscFunctionBegin;
632c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
633db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
634a49dc2a2SStefano Zampini   if (A->spd) {
63500121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6368b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
63700121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
638a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
639a49dc2a2SStefano Zampini   } else if (A->hermitian) {
640a49dc2a2SStefano Zampini     if (!mat->pivots) {
641a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
642a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
643a49dc2a2SStefano Zampini     }
644a49dc2a2SStefano Zampini     if (!mat->fwork) {
645a49dc2a2SStefano Zampini       PetscScalar dummy;
646a49dc2a2SStefano Zampini 
647a49dc2a2SStefano Zampini       mat->lfwork = -1;
64800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
649a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
65000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
651a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
652a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
653a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
654a49dc2a2SStefano Zampini     }
65500121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
656a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
65700121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
658a49dc2a2SStefano Zampini #endif
659a49dc2a2SStefano Zampini   } else { /* symmetric case */
660a49dc2a2SStefano Zampini     if (!mat->pivots) {
661a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
662a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
663a49dc2a2SStefano Zampini     }
664a49dc2a2SStefano Zampini     if (!mat->fwork) {
665a49dc2a2SStefano Zampini       PetscScalar dummy;
666a49dc2a2SStefano Zampini 
667a49dc2a2SStefano Zampini       mat->lfwork = -1;
66800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
669a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
67000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
671a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
672a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
673a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
674a49dc2a2SStefano Zampini     }
67500121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
676a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
67700121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
678a49dc2a2SStefano Zampini   }
679e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
6808208b9aeSStefano Zampini 
681db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6828208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
683db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
684d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
6852205254eSKarl Rupp 
686f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
687f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
688f6224b95SHong Zhang 
689eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
690db4efbfdSBarry Smith   PetscFunctionReturn(0);
691db4efbfdSBarry Smith }
692db4efbfdSBarry Smith 
693db4efbfdSBarry Smith 
6940481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
695db4efbfdSBarry Smith {
696db4efbfdSBarry Smith   PetscErrorCode ierr;
697db4efbfdSBarry Smith   MatFactorInfo  info;
698db4efbfdSBarry Smith 
699db4efbfdSBarry Smith   PetscFunctionBegin;
700db4efbfdSBarry Smith   info.fill = 1.0;
7012205254eSKarl Rupp 
702c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
703ca15aa20SStefano Zampini   ierr = (*fact->ops->choleskyfactor)(fact,0,&info);CHKERRQ(ierr);
704db4efbfdSBarry Smith   PetscFunctionReturn(0);
705db4efbfdSBarry Smith }
706db4efbfdSBarry Smith 
707ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
708db4efbfdSBarry Smith {
709db4efbfdSBarry Smith   PetscFunctionBegin;
710c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
7111bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
712719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
713bd443b22SStefano Zampini   fact->ops->solve                 = MatSolve_SeqDense;
714bd443b22SStefano Zampini   fact->ops->matsolve              = MatMatSolve_SeqDense;
715bd443b22SStefano Zampini   fact->ops->solvetranspose        = MatSolveTranspose_SeqDense;
716db4efbfdSBarry Smith   PetscFunctionReturn(0);
717db4efbfdSBarry Smith }
718db4efbfdSBarry Smith 
719ca15aa20SStefano Zampini PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
720db4efbfdSBarry Smith {
721db4efbfdSBarry Smith   PetscFunctionBegin;
722b66fe19dSMatthew G Knepley   fact->preallocated           = PETSC_TRUE;
723c3ef05f6SHong Zhang   fact->assembled              = PETSC_TRUE;
724719d5645SBarry Smith   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
725bd443b22SStefano Zampini   fact->ops->solve             = MatSolve_SeqDense;
726bd443b22SStefano Zampini   fact->ops->matsolve          = MatMatSolve_SeqDense;
727bd443b22SStefano Zampini   fact->ops->solvetranspose    = MatSolveTranspose_SeqDense;
728db4efbfdSBarry Smith   PetscFunctionReturn(0);
729db4efbfdSBarry Smith }
730db4efbfdSBarry Smith 
731ca15aa20SStefano Zampini /* uses LAPACK */
732cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
733db4efbfdSBarry Smith {
734db4efbfdSBarry Smith   PetscErrorCode ierr;
735db4efbfdSBarry Smith 
736db4efbfdSBarry Smith   PetscFunctionBegin;
737ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
738db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
739ca15aa20SStefano Zampini   ierr = MatSetType(*fact,MATDENSE);CHKERRQ(ierr);
740db4efbfdSBarry Smith   if (ftype == MAT_FACTOR_LU) {
741db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
742db4efbfdSBarry Smith   } else {
743db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
744db4efbfdSBarry Smith   }
745d5f3da31SBarry Smith   (*fact)->factortype = ftype;
74600c67f3bSHong Zhang 
74700c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
74800c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
749db4efbfdSBarry Smith   PetscFunctionReturn(0);
750db4efbfdSBarry Smith }
751db4efbfdSBarry Smith 
752289bc588SBarry Smith /* ------------------------------------------------------------------*/
753e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
754289bc588SBarry Smith {
755c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
756d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
757d9ca1df4SBarry Smith   const PetscScalar *b;
758dfbe8321SBarry Smith   PetscErrorCode    ierr;
759d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
760c5df96a5SBarry Smith   PetscBLASInt      o = 1,bm;
761289bc588SBarry Smith 
7623a40ed3dSBarry Smith   PetscFunctionBegin;
763ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
764c70f7ee4SJunchao Zhang   if (A->offloadmask == PETSC_OFFLOAD_GPU) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
765ca15aa20SStefano Zampini #endif
766422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
767c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
768289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
7693bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
7702dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
771289bc588SBarry Smith   }
7721ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
773d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
774b965ef7fSBarry Smith   its  = its*lits;
775e32f2f54SBarry 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);
776289bc588SBarry Smith   while (its--) {
777fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
778289bc588SBarry Smith       for (i=0; i<m; i++) {
7793bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
78055a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
781289bc588SBarry Smith       }
782289bc588SBarry Smith     }
783fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
784289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
7853bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
78655a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
787289bc588SBarry Smith       }
788289bc588SBarry Smith     }
789289bc588SBarry Smith   }
790d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
7911ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
7923a40ed3dSBarry Smith   PetscFunctionReturn(0);
793289bc588SBarry Smith }
794289bc588SBarry Smith 
795289bc588SBarry Smith /* -----------------------------------------------------------------*/
796ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
797289bc588SBarry Smith {
798c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
799d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
800d9ca1df4SBarry Smith   PetscScalar       *y;
801dfbe8321SBarry Smith   PetscErrorCode    ierr;
8020805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
803ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
8043a40ed3dSBarry Smith 
8053a40ed3dSBarry Smith   PetscFunctionBegin;
806c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
807c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
808d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8092bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
8105ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8115ac36cfcSBarry Smith     PetscBLASInt i;
8125ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
8135ac36cfcSBarry Smith   } else {
8148b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
8155ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
8165ac36cfcSBarry Smith   }
817d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8182bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
8193a40ed3dSBarry Smith   PetscFunctionReturn(0);
820289bc588SBarry Smith }
821800995b7SMatthew Knepley 
822ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
823289bc588SBarry Smith {
824c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
825d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
826dfbe8321SBarry Smith   PetscErrorCode    ierr;
8270805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
828d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
8293a40ed3dSBarry Smith 
8303a40ed3dSBarry Smith   PetscFunctionBegin;
831c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
832c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
833d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8342bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
8355ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8365ac36cfcSBarry Smith     PetscBLASInt i;
8375ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
8385ac36cfcSBarry Smith   } else {
8398b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
8405ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
8415ac36cfcSBarry Smith   }
842d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8432bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
8443a40ed3dSBarry Smith   PetscFunctionReturn(0);
845289bc588SBarry Smith }
8466ee01492SSatish Balay 
847ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
848289bc588SBarry Smith {
849c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
850d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
851d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
852dfbe8321SBarry Smith   PetscErrorCode    ierr;
8530805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
8543a40ed3dSBarry Smith 
8553a40ed3dSBarry Smith   PetscFunctionBegin;
856c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
857c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
858d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
859600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
860d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8611ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8628b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
863d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8641ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
865dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8663a40ed3dSBarry Smith   PetscFunctionReturn(0);
867289bc588SBarry Smith }
8686ee01492SSatish Balay 
869ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
870289bc588SBarry Smith {
871c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
872d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
873d9ca1df4SBarry Smith   PetscScalar       *y;
874dfbe8321SBarry Smith   PetscErrorCode    ierr;
8750805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
87687828ca2SBarry Smith   PetscScalar       _DOne=1.0;
8773a40ed3dSBarry Smith 
8783a40ed3dSBarry Smith   PetscFunctionBegin;
879c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
880c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
881d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
882600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
883d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8841ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8858b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
886d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8871ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
888dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8893a40ed3dSBarry Smith   PetscFunctionReturn(0);
890289bc588SBarry Smith }
891289bc588SBarry Smith 
892289bc588SBarry Smith /* -----------------------------------------------------------------*/
893e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
894289bc588SBarry Smith {
895c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
8966849ba73SBarry Smith   PetscErrorCode ierr;
89713f74950SBarry Smith   PetscInt       i;
89867e560aaSBarry Smith 
8993a40ed3dSBarry Smith   PetscFunctionBegin;
900d0f46423SBarry Smith   *ncols = A->cmap->n;
901289bc588SBarry Smith   if (cols) {
902854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
903d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
904289bc588SBarry Smith   }
905289bc588SBarry Smith   if (vals) {
906ca15aa20SStefano Zampini     const PetscScalar *v;
907ca15aa20SStefano Zampini 
908ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
909854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
910ca15aa20SStefano Zampini     v   += row;
911d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
912ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
913289bc588SBarry Smith   }
9143a40ed3dSBarry Smith   PetscFunctionReturn(0);
915289bc588SBarry Smith }
9166ee01492SSatish Balay 
917e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
918289bc588SBarry Smith {
919dfbe8321SBarry Smith   PetscErrorCode ierr;
9206e111a19SKarl Rupp 
921606d414cSSatish Balay   PetscFunctionBegin;
922606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
923606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
9243a40ed3dSBarry Smith   PetscFunctionReturn(0);
925289bc588SBarry Smith }
926289bc588SBarry Smith /* ----------------------------------------------------------------*/
927e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
928289bc588SBarry Smith {
929c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
930ca15aa20SStefano Zampini   PetscScalar      *av;
93113f74950SBarry Smith   PetscInt         i,j,idx=0;
932ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
933c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
934ca15aa20SStefano Zampini #endif
935ca15aa20SStefano Zampini   PetscErrorCode   ierr;
936d6dfbf8fSBarry Smith 
9373a40ed3dSBarry Smith   PetscFunctionBegin;
938ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&av);CHKERRQ(ierr);
939289bc588SBarry Smith   if (!mat->roworiented) {
940dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
941289bc588SBarry Smith       for (j=0; j<n; j++) {
942cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
943cf9c20a2SJed 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);
944289bc588SBarry Smith         for (i=0; i<m; i++) {
945cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
946cf9c20a2SJed 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);
947ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
948289bc588SBarry Smith         }
949289bc588SBarry Smith       }
9503a40ed3dSBarry Smith     } else {
951289bc588SBarry Smith       for (j=0; j<n; j++) {
952cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
953cf9c20a2SJed 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);
954289bc588SBarry Smith         for (i=0; i<m; i++) {
955cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
956cf9c20a2SJed 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);
957ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
958289bc588SBarry Smith         }
959289bc588SBarry Smith       }
960289bc588SBarry Smith     }
9613a40ed3dSBarry Smith   } else {
962dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
963e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
964cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
965cf9c20a2SJed 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);
966e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
967cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
968cf9c20a2SJed 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);
969ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
970e8d4e0b9SBarry Smith         }
971e8d4e0b9SBarry Smith       }
9723a40ed3dSBarry Smith     } else {
973289bc588SBarry Smith       for (i=0; i<m; i++) {
974cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
975cf9c20a2SJed 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);
976289bc588SBarry Smith         for (j=0; j<n; j++) {
977cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
978cf9c20a2SJed 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);
979ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
980289bc588SBarry Smith         }
981289bc588SBarry Smith       }
982289bc588SBarry Smith     }
983e8d4e0b9SBarry Smith   }
984ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
985ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
986c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
987c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
988ca15aa20SStefano Zampini #endif
989ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&av);CHKERRQ(ierr);
990ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
991c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
992ca15aa20SStefano Zampini #endif
9933a40ed3dSBarry Smith   PetscFunctionReturn(0);
994289bc588SBarry Smith }
995e8d4e0b9SBarry Smith 
996e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
997ae80bb75SLois Curfman McInnes {
998ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
999ca15aa20SStefano Zampini   const PetscScalar *vv;
100013f74950SBarry Smith   PetscInt          i,j;
1001ca15aa20SStefano Zampini   PetscErrorCode    ierr;
1002ae80bb75SLois Curfman McInnes 
10033a40ed3dSBarry Smith   PetscFunctionBegin;
1004ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1005ae80bb75SLois Curfman McInnes   /* row-oriented output */
1006ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
100797e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1008e32f2f54SBarry 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);
1009ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
10106f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1011e32f2f54SBarry 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);
1012ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1013ae80bb75SLois Curfman McInnes     }
1014ae80bb75SLois Curfman McInnes   }
1015ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
10163a40ed3dSBarry Smith   PetscFunctionReturn(0);
1017ae80bb75SLois Curfman McInnes }
1018ae80bb75SLois Curfman McInnes 
1019289bc588SBarry Smith /* -----------------------------------------------------------------*/
1020289bc588SBarry Smith 
10218491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1022aabbc4fbSShri Abhyankar {
1023aabbc4fbSShri Abhyankar   PetscErrorCode    ierr;
10248491ab44SLisandro Dalcin   PetscBool         skipHeader;
10258491ab44SLisandro Dalcin   PetscViewerFormat format;
10268491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
10278491ab44SLisandro Dalcin   const PetscScalar *v;
10288491ab44SLisandro Dalcin   PetscScalar       *vwork;
1029aabbc4fbSShri Abhyankar 
1030aabbc4fbSShri Abhyankar   PetscFunctionBegin;
10318491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
10328491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
10338491ab44SLisandro Dalcin   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
10348491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1035aabbc4fbSShri Abhyankar 
10368491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
10378491ab44SLisandro Dalcin 
10388491ab44SLisandro Dalcin   /* write matrix header */
10398491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
10408491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
10418491ab44SLisandro Dalcin   if (!skipHeader) {ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);}
10428491ab44SLisandro Dalcin 
10438491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
10448491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
10458491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
10468491ab44SLisandro Dalcin     /* store row lengths for each row */
10478491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
10488491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
10498491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
10508491ab44SLisandro Dalcin     /* store column indices (zero start index) */
10518491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
10528491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
10538491ab44SLisandro Dalcin         iwork[k] = j;
10548491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
10558491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
10568491ab44SLisandro Dalcin   }
10578491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
10588491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
10598491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
10608491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
10618491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
10628491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
10638491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
10648491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
10658491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
10668491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
10678491ab44SLisandro Dalcin   PetscFunctionReturn(0);
10688491ab44SLisandro Dalcin }
10698491ab44SLisandro Dalcin 
10708491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
10718491ab44SLisandro Dalcin {
10728491ab44SLisandro Dalcin   PetscErrorCode ierr;
10738491ab44SLisandro Dalcin   PetscBool      skipHeader;
10748491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
10758491ab44SLisandro Dalcin   PetscInt       rows,cols;
10768491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
10778491ab44SLisandro Dalcin 
10788491ab44SLisandro Dalcin   PetscFunctionBegin;
10798491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
10808491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
10818491ab44SLisandro Dalcin 
10828491ab44SLisandro Dalcin   if (!skipHeader) {
10838491ab44SLisandro Dalcin     ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
10848491ab44SLisandro Dalcin     if (header[0] != MAT_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
10858491ab44SLisandro Dalcin     M = header[1]; N = header[2];
10868491ab44SLisandro Dalcin     if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M);
10878491ab44SLisandro Dalcin     if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N);
10888491ab44SLisandro Dalcin     nz = header[3];
10898491ab44SLisandro Dalcin     if (nz != MATRIX_BINARY_FORMAT_DENSE && nz < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %D in file",nz);
1090aabbc4fbSShri Abhyankar   } else {
10918491ab44SLisandro Dalcin     ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
10928491ab44SLisandro 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");
10938491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1094e6324fbbSBarry Smith   }
1095aabbc4fbSShri Abhyankar 
10968491ab44SLisandro Dalcin   /* setup global sizes if not set */
10978491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
10988491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
10998491ab44SLisandro Dalcin   ierr = MatSetUp(mat);CHKERRQ(ierr);
11008491ab44SLisandro Dalcin   /* check if global sizes are correct */
11018491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
11028491ab44SLisandro 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);
1103aabbc4fbSShri Abhyankar 
11048491ab44SLisandro Dalcin   ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
11058491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
11068491ab44SLisandro Dalcin   ierr = MatDenseGetArray(mat,&v);CHKERRQ(ierr);
11078491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
11088491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
11098491ab44SLisandro Dalcin     PetscInt nnz = m*N;
11108491ab44SLisandro Dalcin     /* read in matrix values */
11118491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&vwork);CHKERRQ(ierr);
11128491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
11138491ab44SLisandro Dalcin     /* store values in column major order */
11148491ab44SLisandro Dalcin     for (j=0; j<N; j++)
11158491ab44SLisandro Dalcin       for (i=0; i<m; i++)
11168491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
11178491ab44SLisandro Dalcin     ierr = PetscFree(vwork);CHKERRQ(ierr);
11188491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
11198491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
11208491ab44SLisandro Dalcin     /* read in row lengths */
11218491ab44SLisandro Dalcin     ierr = PetscMalloc1(m,&rlens);CHKERRQ(ierr);
11228491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
11238491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
11248491ab44SLisandro Dalcin     /* read in column indices and values */
11258491ab44SLisandro Dalcin     ierr = PetscMalloc2(nnz,&icols,nnz,&vwork);CHKERRQ(ierr);
11268491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
11278491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
11288491ab44SLisandro Dalcin     /* store values in column major order */
11298491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
11308491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
11318491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
11328491ab44SLisandro Dalcin     ierr = PetscFree(rlens);CHKERRQ(ierr);
11338491ab44SLisandro Dalcin     ierr = PetscFree2(icols,vwork);CHKERRQ(ierr);
1134aabbc4fbSShri Abhyankar   }
11358491ab44SLisandro Dalcin   ierr = MatDenseRestoreArray(mat,&v);CHKERRQ(ierr);
11368491ab44SLisandro Dalcin   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
11378491ab44SLisandro Dalcin   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1138aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1139aabbc4fbSShri Abhyankar }
1140aabbc4fbSShri Abhyankar 
1141eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1142eb91f321SVaclav Hapla {
1143eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1144eb91f321SVaclav Hapla   PetscErrorCode ierr;
1145eb91f321SVaclav Hapla 
1146eb91f321SVaclav Hapla   PetscFunctionBegin;
1147eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1148eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1149eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
1150eb91f321SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1151eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1152eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1153eb91f321SVaclav Hapla   if (isbinary) {
11548491ab44SLisandro Dalcin     ierr = MatLoad_Dense_Binary(newMat,viewer);CHKERRQ(ierr);
1155eb91f321SVaclav Hapla   } else if (ishdf5) {
1156eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
1157eb91f321SVaclav Hapla     ierr = MatLoad_Dense_HDF5(newMat,viewer);CHKERRQ(ierr);
1158eb91f321SVaclav Hapla #else
1159eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1160eb91f321SVaclav Hapla #endif
1161eb91f321SVaclav Hapla   } else {
1162eb91f321SVaclav 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);
1163eb91f321SVaclav Hapla   }
1164eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1165eb91f321SVaclav Hapla }
1166eb91f321SVaclav Hapla 
11676849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1168289bc588SBarry Smith {
1169932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1170dfbe8321SBarry Smith   PetscErrorCode    ierr;
117113f74950SBarry Smith   PetscInt          i,j;
11722dcb1b2aSMatthew Knepley   const char        *name;
1173ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1174f3ef73ceSBarry Smith   PetscViewerFormat format;
11755f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1176ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
11775f481a85SSatish Balay #endif
1178932b0c3eSLois Curfman McInnes 
11793a40ed3dSBarry Smith   PetscFunctionBegin;
1180ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1181b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1182456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
11833a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1184fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1185d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1186d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1187ca15aa20SStefano Zampini       v    = av + i;
118877431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1189d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1190aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1191329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
119257622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1193329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
119457622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
11956831982aSBarry Smith         }
119680cd9d93SLois Curfman McInnes #else
11976831982aSBarry Smith         if (*v) {
119857622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
11996831982aSBarry Smith         }
120080cd9d93SLois Curfman McInnes #endif
12011b807ce4Svictorle         v += a->lda;
120280cd9d93SLois Curfman McInnes       }
1203b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
120480cd9d93SLois Curfman McInnes     }
1205d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
12063a40ed3dSBarry Smith   } else {
1207d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1208aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
120947989497SBarry Smith     /* determine if matrix has all real values */
1210ca15aa20SStefano Zampini     v = av;
1211d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1212ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
121347989497SBarry Smith     }
121447989497SBarry Smith #endif
1215fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
12163a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1217d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1218d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1219fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1220ffac6cdbSBarry Smith     }
1221ffac6cdbSBarry Smith 
1222d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1223ca15aa20SStefano Zampini       v = av + i;
1224d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1225aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
122647989497SBarry Smith         if (allreal) {
1227c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
122847989497SBarry Smith         } else {
1229c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
123047989497SBarry Smith         }
1231289bc588SBarry Smith #else
1232c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1233289bc588SBarry Smith #endif
12341b807ce4Svictorle         v += a->lda;
1235289bc588SBarry Smith       }
1236b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1237289bc588SBarry Smith     }
1238fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1239b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1240ffac6cdbSBarry Smith     }
1241d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1242da3a660dSBarry Smith   }
1243ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1244b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
12453a40ed3dSBarry Smith   PetscFunctionReturn(0);
1246289bc588SBarry Smith }
1247289bc588SBarry Smith 
12489804daf3SBarry Smith #include <petscdraw.h>
1249e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1250f1af5d2fSBarry Smith {
1251f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
12526849ba73SBarry Smith   PetscErrorCode    ierr;
1253383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1254383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1255ca15aa20SStefano Zampini   const PetscScalar *v;
1256b0a32e0cSBarry Smith   PetscViewer       viewer;
1257b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1258f3ef73ceSBarry Smith   PetscViewerFormat format;
1259f1af5d2fSBarry Smith 
1260f1af5d2fSBarry Smith   PetscFunctionBegin;
1261f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1262b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1263b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1264f1af5d2fSBarry Smith 
1265f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1266ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1267fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1268383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1269f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1270f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1271383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1272f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1273f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1274f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1275ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1276ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1277ca15aa20SStefano Zampini         else continue;
1278b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1279f1af5d2fSBarry Smith       }
1280f1af5d2fSBarry Smith     }
1281383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1282f1af5d2fSBarry Smith   } else {
1283f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1284f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1285b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1286b05fc000SLisandro Dalcin     PetscDraw popup;
1287b05fc000SLisandro Dalcin 
1288f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1289f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1290f1af5d2fSBarry Smith     }
1291383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1292b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
129345f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1294383922c3SLisandro Dalcin 
1295383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1296f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1297f1af5d2fSBarry Smith       x_l = j;
1298f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1299f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1300f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1301f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1302b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1303b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1304f1af5d2fSBarry Smith       }
1305f1af5d2fSBarry Smith     }
1306383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1307f1af5d2fSBarry Smith   }
1308ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1309f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1310f1af5d2fSBarry Smith }
1311f1af5d2fSBarry Smith 
1312e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1313f1af5d2fSBarry Smith {
1314b0a32e0cSBarry Smith   PetscDraw      draw;
1315ace3abfcSBarry Smith   PetscBool      isnull;
1316329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1317dfbe8321SBarry Smith   PetscErrorCode ierr;
1318f1af5d2fSBarry Smith 
1319f1af5d2fSBarry Smith   PetscFunctionBegin;
1320b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1321b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1322abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1323f1af5d2fSBarry Smith 
1324d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1325f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1326b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1327832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1328b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
13290298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1330832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1331f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1332f1af5d2fSBarry Smith }
1333f1af5d2fSBarry Smith 
1334dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1335932b0c3eSLois Curfman McInnes {
1336dfbe8321SBarry Smith   PetscErrorCode ierr;
1337ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1338932b0c3eSLois Curfman McInnes 
13393a40ed3dSBarry Smith   PetscFunctionBegin;
1340251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1341251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1342251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
13430f5bd95cSBarry Smith 
1344c45a1595SBarry Smith   if (iascii) {
1345c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
13460f5bd95cSBarry Smith   } else if (isbinary) {
1347*637a0070SStefano Zampini     ierr = MatView_Dense_Binary(A,viewer);CHKERRQ(ierr);
1348f1af5d2fSBarry Smith   } else if (isdraw) {
1349f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1350932b0c3eSLois Curfman McInnes   }
13513a40ed3dSBarry Smith   PetscFunctionReturn(0);
1352932b0c3eSLois Curfman McInnes }
1353289bc588SBarry Smith 
1354*637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array)
1355d3042a70SBarry Smith {
1356d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1357d3042a70SBarry Smith 
1358d3042a70SBarry Smith   PetscFunctionBegin;
1359d3042a70SBarry Smith   a->unplacedarray       = a->v;
1360d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1361d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1362*637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1363ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1364c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1365ca15aa20SStefano Zampini #endif
1366d3042a70SBarry Smith   PetscFunctionReturn(0);
1367d3042a70SBarry Smith }
1368d3042a70SBarry Smith 
1369d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1370d3042a70SBarry Smith {
1371d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1372d3042a70SBarry Smith 
1373d3042a70SBarry Smith   PetscFunctionBegin;
1374d3042a70SBarry Smith   a->v             = a->unplacedarray;
1375d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1376d3042a70SBarry Smith   a->unplacedarray = NULL;
1377ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1378c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1379ca15aa20SStefano Zampini #endif
1380d3042a70SBarry Smith   PetscFunctionReturn(0);
1381d3042a70SBarry Smith }
1382d3042a70SBarry Smith 
1383ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1384289bc588SBarry Smith {
1385ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1386dfbe8321SBarry Smith   PetscErrorCode ierr;
138790f02eecSBarry Smith 
13883a40ed3dSBarry Smith   PetscFunctionBegin;
1389aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1390d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1391a5a9c739SBarry Smith #endif
139205b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1393a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1394abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
13956857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1396*637a0070SStefano Zampini   if (!l->unplaced_user_alloc) {ierr = PetscFree(l->unplacedarray);CHKERRQ(ierr);}
1397bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1398dbd8c25aSHong Zhang 
1399dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
140049a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1401bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
140252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
1403d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1404d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
140552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL);CHKERRQ(ierr);
140652c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL);CHKERRQ(ierr);
14078baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
14088baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
14098baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
14108baccfbdSHong Zhang #endif
14112bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
14122bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL);CHKERRQ(ierr);
14134222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL);CHKERRQ(ierr);
14144222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL);CHKERRQ(ierr);
14154222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaijcusparse_seqdense_C",NULL);CHKERRQ(ierr);
14162bf066beSStefano Zampini #endif
1417bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
14184222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14194222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL);CHKERRQ(ierr);
1420bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1421bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14224222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1423a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1424a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
14254222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
1426c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
1427c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
142852c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
142952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
143052c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
143152c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
143252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
143352c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
143452c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_nest_seqdense_C",NULL);CHKERRQ(ierr);
143552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_nest_seqdense_C",NULL);CHKERRQ(ierr);
143652c5f739Sprj- 
14373bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14383bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
143952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
144052c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
144152c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
144252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
144352c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
144452c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
144586aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
144686aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
14473a40ed3dSBarry Smith   PetscFunctionReturn(0);
1448289bc588SBarry Smith }
1449289bc588SBarry Smith 
1450e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1451289bc588SBarry Smith {
1452c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
14536849ba73SBarry Smith   PetscErrorCode ierr;
145413f74950SBarry Smith   PetscInt       k,j,m,n,M;
145587828ca2SBarry Smith   PetscScalar    *v,tmp;
145648b35521SBarry Smith 
14573a40ed3dSBarry Smith   PetscFunctionBegin;
1458ca15aa20SStefano Zampini   m = A->rmap->n; M = mat->lda; n = A->cmap->n;
14592847e3fdSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX && m == n) { /* in place transpose */
1460ca15aa20SStefano Zampini     ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1461d3e5ee88SLois Curfman McInnes     for (j=0; j<m; j++) {
1462289bc588SBarry Smith       for (k=0; k<j; k++) {
14631b807ce4Svictorle         tmp        = v[j + k*M];
14641b807ce4Svictorle         v[j + k*M] = v[k + j*M];
14651b807ce4Svictorle         v[k + j*M] = tmp;
1466289bc588SBarry Smith       }
1467289bc588SBarry Smith     }
1468ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
14693a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1470d3e5ee88SLois Curfman McInnes     Mat          tmat;
1471ec8511deSBarry Smith     Mat_SeqDense *tmatd;
147287828ca2SBarry Smith     PetscScalar  *v2;
1473af36a384SStefano Zampini     PetscInt     M2;
1474ea709b57SSatish Balay 
14752847e3fdSStefano Zampini     if (reuse != MAT_REUSE_MATRIX) {
1476ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1477d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
14787adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
14790298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1480ca15aa20SStefano Zampini     } else tmat = *matout;
1481ca15aa20SStefano Zampini 
1482ca15aa20SStefano Zampini     ierr  = MatDenseGetArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
1483ca15aa20SStefano Zampini     ierr  = MatDenseGetArray(tmat,&v2);CHKERRQ(ierr);
1484ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1485ca15aa20SStefano Zampini     M2    = tmatd->lda;
1486d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1487af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1488d3e5ee88SLois Curfman McInnes     }
1489ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(tmat,&v2);CHKERRQ(ierr);
1490ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
14916d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14926d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14932847e3fdSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) *matout = tmat;
14942847e3fdSStefano Zampini     else {
14952847e3fdSStefano Zampini       ierr = MatHeaderMerge(A,&tmat);CHKERRQ(ierr);
14962847e3fdSStefano Zampini     }
149748b35521SBarry Smith   }
14983a40ed3dSBarry Smith   PetscFunctionReturn(0);
1499289bc588SBarry Smith }
1500289bc588SBarry Smith 
1501e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1502289bc588SBarry Smith {
1503c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1504c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1505ca15aa20SStefano Zampini   PetscInt          i;
1506ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
1507ca15aa20SStefano Zampini   PetscErrorCode    ierr;
15089ea5d5aeSSatish Balay 
15093a40ed3dSBarry Smith   PetscFunctionBegin;
1510d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1511d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1512ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A1,&v1);CHKERRQ(ierr);
1513ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A2,&v2);CHKERRQ(ierr);
1514ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
1515ca15aa20SStefano Zampini     ierr = PetscArraycmp(v1,v2,A1->rmap->n,flg);CHKERRQ(ierr);
1516ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1517ca15aa20SStefano Zampini     v1 += mat1->lda;
1518ca15aa20SStefano Zampini     v2 += mat2->lda;
15191b807ce4Svictorle   }
1520ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A1,&v1);CHKERRQ(ierr);
1521ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A2,&v2);CHKERRQ(ierr);
152277c4ece6SBarry Smith   *flg = PETSC_TRUE;
15233a40ed3dSBarry Smith   PetscFunctionReturn(0);
1524289bc588SBarry Smith }
1525289bc588SBarry Smith 
1526e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1527289bc588SBarry Smith {
1528c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
152913f74950SBarry Smith   PetscInt          i,n,len;
1530ca15aa20SStefano Zampini   PetscScalar       *x;
1531ca15aa20SStefano Zampini   const PetscScalar *vv;
1532ca15aa20SStefano Zampini   PetscErrorCode    ierr;
153344cd7ae7SLois Curfman McInnes 
15343a40ed3dSBarry Smith   PetscFunctionBegin;
15357a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
15361ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1537d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1538ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1539e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
154044cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1541ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1542289bc588SBarry Smith   }
1543ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
15441ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
15453a40ed3dSBarry Smith   PetscFunctionReturn(0);
1546289bc588SBarry Smith }
1547289bc588SBarry Smith 
1548e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1549289bc588SBarry Smith {
1550c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1551f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1552ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1553dfbe8321SBarry Smith   PetscErrorCode    ierr;
1554d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
155555659b69SBarry Smith 
15563a40ed3dSBarry Smith   PetscFunctionBegin;
1557ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&vv);CHKERRQ(ierr);
155828988994SBarry Smith   if (ll) {
15597a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1560f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1561e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1562da3a660dSBarry Smith     for (i=0; i<m; i++) {
1563da3a660dSBarry Smith       x = l[i];
1564ca15aa20SStefano Zampini       v = vv + i;
1565b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1566da3a660dSBarry Smith     }
1567f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1568eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1569da3a660dSBarry Smith   }
157028988994SBarry Smith   if (rr) {
15717a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1572f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1573e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1574da3a660dSBarry Smith     for (i=0; i<n; i++) {
1575da3a660dSBarry Smith       x = r[i];
1576ca15aa20SStefano Zampini       v = vv + i*mat->lda;
15772205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1578da3a660dSBarry Smith     }
1579f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1580eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1581da3a660dSBarry Smith   }
1582ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&vv);CHKERRQ(ierr);
15833a40ed3dSBarry Smith   PetscFunctionReturn(0);
1584289bc588SBarry Smith }
1585289bc588SBarry Smith 
1586ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1587289bc588SBarry Smith {
1588c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1589ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1590329f5518SBarry Smith   PetscReal         sum  = 0.0;
1591d0f46423SBarry Smith   PetscInt          lda  =mat->lda,m=A->rmap->n,i,j;
1592efee365bSSatish Balay   PetscErrorCode    ierr;
159355659b69SBarry Smith 
15943a40ed3dSBarry Smith   PetscFunctionBegin;
1595ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
1596ca15aa20SStefano Zampini   v    = vv;
1597289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1598a5ce6ee0Svictorle     if (lda>m) {
1599d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1600ca15aa20SStefano Zampini         v = vv+j*lda;
1601a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1602a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1603a5ce6ee0Svictorle         }
1604a5ce6ee0Svictorle       }
1605a5ce6ee0Svictorle     } else {
1606570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1607570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1608570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1609570b7f6dSBarry Smith     }
1610570b7f6dSBarry Smith #else
1611d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1612329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1613289bc588SBarry Smith       }
1614a5ce6ee0Svictorle     }
16158f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1616570b7f6dSBarry Smith #endif
1617dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16183a40ed3dSBarry Smith   } else if (type == NORM_1) {
1619064f8208SBarry Smith     *nrm = 0.0;
1620d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1621ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
1622289bc588SBarry Smith       sum = 0.0;
1623d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
162433a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1625289bc588SBarry Smith       }
1626064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1627289bc588SBarry Smith     }
1628eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16293a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1630064f8208SBarry Smith     *nrm = 0.0;
1631d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1632ca15aa20SStefano Zampini       v   = vv + j;
1633289bc588SBarry Smith       sum = 0.0;
1634d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
16351b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1636289bc588SBarry Smith       }
1637064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1638289bc588SBarry Smith     }
1639eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1640e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
1641ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
16423a40ed3dSBarry Smith   PetscFunctionReturn(0);
1643289bc588SBarry Smith }
1644289bc588SBarry Smith 
1645e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1646289bc588SBarry Smith {
1647c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
164863ba0a88SBarry Smith   PetscErrorCode ierr;
164967e560aaSBarry Smith 
16503a40ed3dSBarry Smith   PetscFunctionBegin;
1651b5a2b587SKris Buschelman   switch (op) {
1652b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
16534e0d8c25SBarry Smith     aij->roworiented = flg;
1654b5a2b587SKris Buschelman     break;
1655512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1656b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
16573971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
16584e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
165913fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1660b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1661b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
16620f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
16635021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
1664071fcb05SBarry Smith   case MAT_SORTED_FULL:
16655021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
16665021d80fSJed Brown     break;
16675021d80fSJed Brown   case MAT_SPD:
166877e54ba9SKris Buschelman   case MAT_SYMMETRIC:
166977e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
16709a4540c5SBarry Smith   case MAT_HERMITIAN:
16719a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
16725021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
167377e54ba9SKris Buschelman     break;
1674b5a2b587SKris Buschelman   default:
1675e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
16763a40ed3dSBarry Smith   }
16773a40ed3dSBarry Smith   PetscFunctionReturn(0);
1678289bc588SBarry Smith }
1679289bc588SBarry Smith 
1680e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
16816f0a148fSBarry Smith {
1682ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
16836849ba73SBarry Smith   PetscErrorCode ierr;
1684d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
1685ca15aa20SStefano Zampini   PetscScalar    *v;
16863a40ed3dSBarry Smith 
16873a40ed3dSBarry Smith   PetscFunctionBegin;
1688ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1689a5ce6ee0Svictorle   if (lda>m) {
1690d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1691ca15aa20SStefano Zampini       ierr = PetscArrayzero(v+j*lda,m);CHKERRQ(ierr);
1692a5ce6ee0Svictorle     }
1693a5ce6ee0Svictorle   } else {
1694ca15aa20SStefano Zampini     ierr = PetscArrayzero(v,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
1695a5ce6ee0Svictorle   }
1696ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
16973a40ed3dSBarry Smith   PetscFunctionReturn(0);
16986f0a148fSBarry Smith }
16996f0a148fSBarry Smith 
1700e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
17016f0a148fSBarry Smith {
170297b48c8fSBarry Smith   PetscErrorCode    ierr;
1703ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1704b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
1705ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
170697b48c8fSBarry Smith   const PetscScalar *xx;
170755659b69SBarry Smith 
17083a40ed3dSBarry Smith   PetscFunctionBegin;
170976bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1710b9679d65SBarry Smith     for (i=0; i<N; i++) {
1711b9679d65SBarry Smith       if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1712b9679d65SBarry 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);
1713b9679d65SBarry Smith     }
171476bd3646SJed Brown   }
1715ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1716b9679d65SBarry Smith 
171797b48c8fSBarry Smith   /* fix right hand side if needed */
171897b48c8fSBarry Smith   if (x && b) {
171997b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
172097b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
17212205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
172297b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
172397b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
172497b48c8fSBarry Smith   }
172597b48c8fSBarry Smith 
1726ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
17276f0a148fSBarry Smith   for (i=0; i<N; i++) {
1728ca15aa20SStefano Zampini     slot = v + rows[i];
1729b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
17306f0a148fSBarry Smith   }
1731f4df32b1SMatthew Knepley   if (diag != 0.0) {
1732b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
17336f0a148fSBarry Smith     for (i=0; i<N; i++) {
1734ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1735f4df32b1SMatthew Knepley       *slot = diag;
17366f0a148fSBarry Smith     }
17376f0a148fSBarry Smith   }
1738ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17393a40ed3dSBarry Smith   PetscFunctionReturn(0);
17406f0a148fSBarry Smith }
1741557bce09SLois Curfman McInnes 
174249a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
174349a6ff4bSBarry Smith {
174449a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
174549a6ff4bSBarry Smith 
174649a6ff4bSBarry Smith   PetscFunctionBegin;
174749a6ff4bSBarry Smith   *lda = mat->lda;
174849a6ff4bSBarry Smith   PetscFunctionReturn(0);
174949a6ff4bSBarry Smith }
175049a6ff4bSBarry Smith 
1751*637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array)
175264e87e97SBarry Smith {
1753c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
17543a40ed3dSBarry Smith 
17553a40ed3dSBarry Smith   PetscFunctionBegin;
175664e87e97SBarry Smith   *array = mat->v;
17573a40ed3dSBarry Smith   PetscFunctionReturn(0);
175864e87e97SBarry Smith }
17590754003eSLois Curfman McInnes 
1760*637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array)
1761ff14e315SSatish Balay {
17623a40ed3dSBarry Smith   PetscFunctionBegin;
1763*637a0070SStefano Zampini   *array = NULL;
17643a40ed3dSBarry Smith   PetscFunctionReturn(0);
1765ff14e315SSatish Balay }
17660754003eSLois Curfman McInnes 
1767dec5eb66SMatthew G Knepley /*@C
176849a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
176949a6ff4bSBarry Smith 
177049a6ff4bSBarry Smith    Logically Collective on Mat
177149a6ff4bSBarry Smith 
177249a6ff4bSBarry Smith    Input Parameter:
177349a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
177449a6ff4bSBarry Smith 
177549a6ff4bSBarry Smith    Output Parameter:
177649a6ff4bSBarry Smith .   lda - the leading dimension
177749a6ff4bSBarry Smith 
177849a6ff4bSBarry Smith    Level: intermediate
177949a6ff4bSBarry Smith 
178049a6ff4bSBarry Smith .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatSeqDenseSetLDA()
178149a6ff4bSBarry Smith @*/
178249a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
178349a6ff4bSBarry Smith {
178449a6ff4bSBarry Smith   PetscErrorCode ierr;
178549a6ff4bSBarry Smith 
178649a6ff4bSBarry Smith   PetscFunctionBegin;
178749a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
178849a6ff4bSBarry Smith   PetscFunctionReturn(0);
178949a6ff4bSBarry Smith }
179049a6ff4bSBarry Smith 
179149a6ff4bSBarry Smith /*@C
17928c778c55SBarry Smith    MatDenseGetArray - gives access to the array where the data for a SeqDense matrix is stored
179373a71a0fSBarry Smith 
17948572280aSBarry Smith    Logically Collective on Mat
179573a71a0fSBarry Smith 
179673a71a0fSBarry Smith    Input Parameter:
1797579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
179873a71a0fSBarry Smith 
179973a71a0fSBarry Smith    Output Parameter:
180073a71a0fSBarry Smith .   array - pointer to the data
180173a71a0fSBarry Smith 
180273a71a0fSBarry Smith    Level: intermediate
180373a71a0fSBarry Smith 
18048572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
180573a71a0fSBarry Smith @*/
18068c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
180773a71a0fSBarry Smith {
180873a71a0fSBarry Smith   PetscErrorCode ierr;
180973a71a0fSBarry Smith 
181073a71a0fSBarry Smith   PetscFunctionBegin;
18118c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
181273a71a0fSBarry Smith   PetscFunctionReturn(0);
181373a71a0fSBarry Smith }
181473a71a0fSBarry Smith 
1815dec5eb66SMatthew G Knepley /*@C
1816579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
181773a71a0fSBarry Smith 
18188572280aSBarry Smith    Logically Collective on Mat
18198572280aSBarry Smith 
18208572280aSBarry Smith    Input Parameters:
1821a2b725a8SWilliam Gropp +  mat - a MATSEQDENSE or MATMPIDENSE matrix
1822a2b725a8SWilliam Gropp -  array - pointer to the data
18238572280aSBarry Smith 
18248572280aSBarry Smith    Level: intermediate
18258572280aSBarry Smith 
18268572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
18278572280aSBarry Smith @*/
18288572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
18298572280aSBarry Smith {
18308572280aSBarry Smith   PetscErrorCode ierr;
18318572280aSBarry Smith 
18328572280aSBarry Smith   PetscFunctionBegin;
18338572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
18348572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
1835*637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1836*637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1837*637a0070SStefano Zampini #endif
18388572280aSBarry Smith   PetscFunctionReturn(0);
18398572280aSBarry Smith }
18408572280aSBarry Smith 
18418572280aSBarry Smith /*@C
18428572280aSBarry Smith    MatDenseGetArrayRead - gives access to the array where the data for a SeqDense matrix is stored
18438572280aSBarry Smith 
18448572280aSBarry Smith    Not Collective
18458572280aSBarry Smith 
18468572280aSBarry Smith    Input Parameter:
18478572280aSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
18488572280aSBarry Smith 
18498572280aSBarry Smith    Output Parameter:
18508572280aSBarry Smith .   array - pointer to the data
18518572280aSBarry Smith 
18528572280aSBarry Smith    Level: intermediate
18538572280aSBarry Smith 
18548572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArray(), MatDenseRestoreArrayRead()
18558572280aSBarry Smith @*/
18568572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
18578572280aSBarry Smith {
18588572280aSBarry Smith   PetscErrorCode ierr;
18598572280aSBarry Smith 
18608572280aSBarry Smith   PetscFunctionBegin;
18618572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
18628572280aSBarry Smith   PetscFunctionReturn(0);
18638572280aSBarry Smith }
18648572280aSBarry Smith 
18658572280aSBarry Smith /*@C
18668572280aSBarry Smith    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
18678572280aSBarry Smith 
186873a71a0fSBarry Smith    Not Collective
186973a71a0fSBarry Smith 
187073a71a0fSBarry Smith    Input Parameters:
1871a2b725a8SWilliam Gropp +  mat - a MATSEQDENSE or MATMPIDENSE matrix
1872a2b725a8SWilliam Gropp -  array - pointer to the data
187373a71a0fSBarry Smith 
187473a71a0fSBarry Smith    Level: intermediate
187573a71a0fSBarry Smith 
18768572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArray()
187773a71a0fSBarry Smith @*/
18788572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
187973a71a0fSBarry Smith {
188073a71a0fSBarry Smith   PetscErrorCode ierr;
188173a71a0fSBarry Smith 
188273a71a0fSBarry Smith   PetscFunctionBegin;
18838572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
188473a71a0fSBarry Smith   PetscFunctionReturn(0);
188573a71a0fSBarry Smith }
188673a71a0fSBarry Smith 
18877dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
18880754003eSLois Curfman McInnes {
1889c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
18906849ba73SBarry Smith   PetscErrorCode ierr;
1891ca15aa20SStefano Zampini   PetscInt       i,j,nrows,ncols,blda;
18925d0c19d7SBarry Smith   const PetscInt *irow,*icol;
189387828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
18940754003eSLois Curfman McInnes   Mat            newmat;
18950754003eSLois Curfman McInnes 
18963a40ed3dSBarry Smith   PetscFunctionBegin;
189778b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
189878b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1899e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1900e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
19010754003eSLois Curfman McInnes 
1902182d2002SSatish Balay   /* Check submatrixcall */
1903182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
190413f74950SBarry Smith     PetscInt n_cols,n_rows;
1905182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
190621a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
1907f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
1908c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
190921a2c019SBarry Smith     }
1910182d2002SSatish Balay     newmat = *B;
1911182d2002SSatish Balay   } else {
19120754003eSLois Curfman McInnes     /* Create and fill new matrix */
1913ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
1914f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
19157adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
19160298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1917182d2002SSatish Balay   }
1918182d2002SSatish Balay 
1919182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1920ca15aa20SStefano Zampini   ierr = MatDenseGetArray(newmat,&bv);CHKERRQ(ierr);
1921ca15aa20SStefano Zampini   ierr = MatDenseGetLDA(newmat,&blda);CHKERRQ(ierr);
1922182d2002SSatish Balay   for (i=0; i<ncols; i++) {
19236de62eeeSBarry Smith     av = v + mat->lda*icol[i];
1924ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
1925ca15aa20SStefano Zampini     bv += blda;
19260754003eSLois Curfman McInnes   }
1927ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(newmat,&bv);CHKERRQ(ierr);
1928182d2002SSatish Balay 
1929182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
19306d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19316d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19320754003eSLois Curfman McInnes 
19330754003eSLois Curfman McInnes   /* Free work space */
193478b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
193578b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1936182d2002SSatish Balay   *B   = newmat;
19373a40ed3dSBarry Smith   PetscFunctionReturn(0);
19380754003eSLois Curfman McInnes }
19390754003eSLois Curfman McInnes 
19407dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1941905e6a2fSBarry Smith {
19426849ba73SBarry Smith   PetscErrorCode ierr;
194313f74950SBarry Smith   PetscInt       i;
1944905e6a2fSBarry Smith 
19453a40ed3dSBarry Smith   PetscFunctionBegin;
1946905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1947df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
1948905e6a2fSBarry Smith   }
1949905e6a2fSBarry Smith 
1950905e6a2fSBarry Smith   for (i=0; i<n; i++) {
19517dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1952905e6a2fSBarry Smith   }
19533a40ed3dSBarry Smith   PetscFunctionReturn(0);
1954905e6a2fSBarry Smith }
1955905e6a2fSBarry Smith 
1956e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
1957c0aa2d19SHong Zhang {
1958c0aa2d19SHong Zhang   PetscFunctionBegin;
1959c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1960c0aa2d19SHong Zhang }
1961c0aa2d19SHong Zhang 
1962e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
1963c0aa2d19SHong Zhang {
1964c0aa2d19SHong Zhang   PetscFunctionBegin;
1965c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1966c0aa2d19SHong Zhang }
1967c0aa2d19SHong Zhang 
1968e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
19694b0e389bSBarry Smith {
19704b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
19716849ba73SBarry Smith   PetscErrorCode    ierr;
1972ca15aa20SStefano Zampini   const PetscScalar *va;
1973ca15aa20SStefano Zampini   PetscScalar       *vb;
1974d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
19753a40ed3dSBarry Smith 
19763a40ed3dSBarry Smith   PetscFunctionBegin;
197733f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
197833f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
1979cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
19803a40ed3dSBarry Smith     PetscFunctionReturn(0);
19813a40ed3dSBarry Smith   }
1982e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
1983ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&va);CHKERRQ(ierr);
1984ca15aa20SStefano Zampini   ierr = MatDenseGetArray(B,&vb);CHKERRQ(ierr);
1985a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
19860dbb7854Svictorle     for (j=0; j<n; j++) {
1987ca15aa20SStefano Zampini       ierr = PetscArraycpy(vb+j*lda2,va+j*lda1,m);CHKERRQ(ierr);
1988a5ce6ee0Svictorle     }
1989a5ce6ee0Svictorle   } else {
1990ca15aa20SStefano Zampini     ierr = PetscArraycpy(vb,va,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
1991a5ce6ee0Svictorle   }
1992ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(B,&vb);CHKERRQ(ierr);
1993ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&va);CHKERRQ(ierr);
1994ca15aa20SStefano Zampini   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1995ca15aa20SStefano Zampini   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1996273d9f13SBarry Smith   PetscFunctionReturn(0);
1997273d9f13SBarry Smith }
1998273d9f13SBarry Smith 
1999e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
2000273d9f13SBarry Smith {
2001dfbe8321SBarry Smith   PetscErrorCode ierr;
2002273d9f13SBarry Smith 
2003273d9f13SBarry Smith   PetscFunctionBegin;
200418992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
200518992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
200618992e5dSStefano Zampini   if (!A->preallocated) {
2007273d9f13SBarry Smith     ierr = MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
200818992e5dSStefano Zampini   }
20093a40ed3dSBarry Smith   PetscFunctionReturn(0);
20104b0e389bSBarry Smith }
20114b0e389bSBarry Smith 
2012ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2013ba337c44SJed Brown {
2014ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2015ca15aa20SStefano Zampini   PetscScalar    *aa;
2016ca15aa20SStefano Zampini   PetscErrorCode ierr;
2017ba337c44SJed Brown 
2018ba337c44SJed Brown   PetscFunctionBegin;
2019ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2020ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2021ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2022ba337c44SJed Brown   PetscFunctionReturn(0);
2023ba337c44SJed Brown }
2024ba337c44SJed Brown 
2025ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2026ba337c44SJed Brown {
2027ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2028ca15aa20SStefano Zampini   PetscScalar    *aa;
2029ca15aa20SStefano Zampini   PetscErrorCode ierr;
2030ba337c44SJed Brown 
2031ba337c44SJed Brown   PetscFunctionBegin;
2032ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2033ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2034ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2035ba337c44SJed Brown   PetscFunctionReturn(0);
2036ba337c44SJed Brown }
2037ba337c44SJed Brown 
2038ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2039ba337c44SJed Brown {
2040ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2041ca15aa20SStefano Zampini   PetscScalar    *aa;
2042ca15aa20SStefano Zampini   PetscErrorCode ierr;
2043ba337c44SJed Brown 
2044ba337c44SJed Brown   PetscFunctionBegin;
2045ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2046ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
2047ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2048ba337c44SJed Brown   PetscFunctionReturn(0);
2049ba337c44SJed Brown }
2050284134d9SBarry Smith 
2051a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
20524222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2053a9fe9ddaSSatish Balay {
2054ee16a9a1SHong Zhang   PetscErrorCode ierr;
2055d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
2056ca15aa20SStefano Zampini   PetscBool      flg;
2057a9fe9ddaSSatish Balay 
2058ee16a9a1SHong Zhang   PetscFunctionBegin;
20594222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
2060ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
20614222ddf1SHong Zhang   ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
206218992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2063ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2064ee16a9a1SHong Zhang }
2065a9fe9ddaSSatish Balay 
2066a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2067a9fe9ddaSSatish Balay {
206852c5f739Sprj-   Mat_SeqDense       *a,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
20690805154bSBarry Smith   PetscBLASInt       m,n,k;
2070ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2071ca15aa20SStefano Zampini   PetscScalar       *cv;
2072a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2073fd4e9aacSBarry Smith   PetscBool         flg;
2074c2916339SPierre Jolivet   PetscErrorCode    (*numeric)(Mat,Mat,Mat)=NULL;
2075c2916339SPierre Jolivet   PetscErrorCode    ierr;
2076a9fe9ddaSSatish Balay 
2077a9fe9ddaSSatish Balay   PetscFunctionBegin;
2078fd4e9aacSBarry Smith   /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/
2079fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
2080c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqAIJ_SeqDense;
2081a001520aSPierre Jolivet   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQBAIJ,&flg);CHKERRQ(ierr);
2082c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqBAIJ_SeqDense;
2083c2916339SPierre Jolivet   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQSBAIJ,&flg);CHKERRQ(ierr);
2084c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqSBAIJ_SeqDense;
208552c5f739Sprj-   ierr = PetscObjectTypeCompare((PetscObject)A,MATNEST,&flg);CHKERRQ(ierr);
2086c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_Nest_Dense;
2087c2916339SPierre Jolivet   if (numeric) {
2088c2916339SPierre Jolivet     C->ops->matmultnumeric = numeric;
2089c2916339SPierre Jolivet     ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
209052c5f739Sprj-     PetscFunctionReturn(0);
209152c5f739Sprj-   }
209252c5f739Sprj-   a = (Mat_SeqDense*)A->data;
20938208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
20948208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2095c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
209649d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
2097ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
2098ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
2099ca15aa20SStefano Zampini   ierr = MatDenseGetArray(C,&cv);CHKERRQ(ierr);
2100ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
2101ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2102ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
2103ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
2104ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(C,&cv);CHKERRQ(ierr);
2105a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2106a9fe9ddaSSatish Balay }
2107a9fe9ddaSSatish Balay 
21084222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
210969f65d41SStefano Zampini {
211069f65d41SStefano Zampini   PetscErrorCode ierr;
211169f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
2112ca15aa20SStefano Zampini   PetscBool      flg;
211369f65d41SStefano Zampini 
211469f65d41SStefano Zampini   PetscFunctionBegin;
21154222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
2116ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
21174222ddf1SHong Zhang   ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
211818992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
211969f65d41SStefano Zampini   PetscFunctionReturn(0);
212069f65d41SStefano Zampini }
212169f65d41SStefano Zampini 
212269f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
212369f65d41SStefano Zampini {
212469f65d41SStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
212569f65d41SStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
212669f65d41SStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
212769f65d41SStefano Zampini   PetscBLASInt   m,n,k;
212869f65d41SStefano Zampini   PetscScalar    _DOne=1.0,_DZero=0.0;
212969f65d41SStefano Zampini   PetscErrorCode ierr;
213069f65d41SStefano Zampini 
213169f65d41SStefano Zampini   PetscFunctionBegin;
213249d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
213349d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
213469f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
213549d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
213669f65d41SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2137ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
213869f65d41SStefano Zampini   PetscFunctionReturn(0);
213969f65d41SStefano Zampini }
214069f65d41SStefano Zampini 
21414222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2142a9fe9ddaSSatish Balay {
2143ee16a9a1SHong Zhang   PetscErrorCode ierr;
2144d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
2145ca15aa20SStefano Zampini   PetscBool      flg;
2146a9fe9ddaSSatish Balay 
2147ee16a9a1SHong Zhang   PetscFunctionBegin;
21484222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
2149ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
21504222ddf1SHong Zhang   ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
215118992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2152ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2153ee16a9a1SHong Zhang }
2154a9fe9ddaSSatish Balay 
215575648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2156a9fe9ddaSSatish Balay {
2157a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2158a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2159a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
21600805154bSBarry Smith   PetscBLASInt   m,n,k;
2161a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
2162c5df96a5SBarry Smith   PetscErrorCode ierr;
2163a9fe9ddaSSatish Balay 
2164a9fe9ddaSSatish Balay   PetscFunctionBegin;
21658208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
21668208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2167c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
216849d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
21695ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2170ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2171a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2172a9fe9ddaSSatish Balay }
2173985db425SBarry Smith 
21744222ddf1SHong Zhang /* ----------------------------------------------- */
21754222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
21764222ddf1SHong Zhang {
21774222ddf1SHong Zhang   PetscFunctionBegin;
21784222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
21794222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
21804222ddf1SHong Zhang   /* dense mat may not call MatProductSymbolic(), thus set C->ops->productnumeric here */
21814222ddf1SHong Zhang   C->ops->productnumeric  = MatProductNumeric_AB;
21824222ddf1SHong Zhang   PetscFunctionReturn(0);
21834222ddf1SHong Zhang }
21844222ddf1SHong Zhang 
21854222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
21864222ddf1SHong Zhang {
21874222ddf1SHong Zhang   PetscFunctionBegin;
21884222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
21894222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
21904222ddf1SHong Zhang   C->ops->productnumeric           = MatProductNumeric_AtB;
21914222ddf1SHong Zhang   PetscFunctionReturn(0);
21924222ddf1SHong Zhang }
21934222ddf1SHong Zhang 
21944222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
21954222ddf1SHong Zhang {
21964222ddf1SHong Zhang   PetscFunctionBegin;
21974222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
21984222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
21994222ddf1SHong Zhang   C->ops->productnumeric           = MatProductNumeric_ABt;
22004222ddf1SHong Zhang   PetscFunctionReturn(0);
22014222ddf1SHong Zhang }
22024222ddf1SHong Zhang 
22034222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_PtAP(Mat C)
22044222ddf1SHong Zhang {
22054222ddf1SHong Zhang   PetscFunctionBegin;
22064222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_Basic;
22074222ddf1SHong Zhang   PetscFunctionReturn(0);
22084222ddf1SHong Zhang }
22094222ddf1SHong Zhang 
22104222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
22114222ddf1SHong Zhang {
22124222ddf1SHong Zhang   PetscErrorCode ierr;
22134222ddf1SHong Zhang   Mat_Product    *product = C->product;
22144222ddf1SHong Zhang 
22154222ddf1SHong Zhang   PetscFunctionBegin;
22164222ddf1SHong Zhang   switch (product->type) {
22174222ddf1SHong Zhang   case MATPRODUCT_AB:
22184222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AB(C);CHKERRQ(ierr);
22194222ddf1SHong Zhang     break;
22204222ddf1SHong Zhang   case MATPRODUCT_AtB:
22214222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AtB(C);CHKERRQ(ierr);
22224222ddf1SHong Zhang     break;
22234222ddf1SHong Zhang   case MATPRODUCT_ABt:
22244222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_ABt(C);CHKERRQ(ierr);
22254222ddf1SHong Zhang     break;
22264222ddf1SHong Zhang   case MATPRODUCT_PtAP:
22274222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_PtAP(C);CHKERRQ(ierr);
22284222ddf1SHong Zhang     break;
2229544a5e07SHong Zhang   default: SETERRQ1(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProduct type %s is not supported for SeqDense and SeqDense matrices",MatProductTypes[product->type]);
22304222ddf1SHong Zhang   }
22314222ddf1SHong Zhang   PetscFunctionReturn(0);
22324222ddf1SHong Zhang }
22334222ddf1SHong Zhang /* ----------------------------------------------- */
22344222ddf1SHong Zhang 
2235e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2236985db425SBarry Smith {
2237985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2238985db425SBarry Smith   PetscErrorCode     ierr;
2239d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2240985db425SBarry Smith   PetscScalar        *x;
2241ca15aa20SStefano Zampini   const PetscScalar *aa;
2242985db425SBarry Smith 
2243985db425SBarry Smith   PetscFunctionBegin;
2244e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2245985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2246985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2247ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2248e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2249985db425SBarry Smith   for (i=0; i<m; i++) {
2250985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2251985db425SBarry Smith     for (j=1; j<n; j++) {
2252ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2253985db425SBarry Smith     }
2254985db425SBarry Smith   }
2255ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2256985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2257985db425SBarry Smith   PetscFunctionReturn(0);
2258985db425SBarry Smith }
2259985db425SBarry Smith 
2260e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2261985db425SBarry Smith {
2262985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2263985db425SBarry Smith   PetscErrorCode    ierr;
2264d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2265985db425SBarry Smith   PetscScalar       *x;
2266985db425SBarry Smith   PetscReal         atmp;
2267ca15aa20SStefano Zampini   const PetscScalar *aa;
2268985db425SBarry Smith 
2269985db425SBarry Smith   PetscFunctionBegin;
2270e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2271985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2272985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2273ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2274e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2275985db425SBarry Smith   for (i=0; i<m; i++) {
22769189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2277985db425SBarry Smith     for (j=1; j<n; j++) {
2278ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2279985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2280985db425SBarry Smith     }
2281985db425SBarry Smith   }
2282ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2283985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2284985db425SBarry Smith   PetscFunctionReturn(0);
2285985db425SBarry Smith }
2286985db425SBarry Smith 
2287e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2288985db425SBarry Smith {
2289985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2290985db425SBarry Smith   PetscErrorCode    ierr;
2291d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2292985db425SBarry Smith   PetscScalar       *x;
2293ca15aa20SStefano Zampini   const PetscScalar *aa;
2294985db425SBarry Smith 
2295985db425SBarry Smith   PetscFunctionBegin;
2296e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2297ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2298985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2299985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2300e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2301985db425SBarry Smith   for (i=0; i<m; i++) {
2302985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2303985db425SBarry Smith     for (j=1; j<n; j++) {
2304ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2305985db425SBarry Smith     }
2306985db425SBarry Smith   }
2307985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2308ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2309985db425SBarry Smith   PetscFunctionReturn(0);
2310985db425SBarry Smith }
2311985db425SBarry Smith 
2312*637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
23138d0534beSBarry Smith {
23148d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
23158d0534beSBarry Smith   PetscErrorCode    ierr;
23168d0534beSBarry Smith   PetscScalar       *x;
2317ca15aa20SStefano Zampini   const PetscScalar *aa;
23188d0534beSBarry Smith 
23198d0534beSBarry Smith   PetscFunctionBegin;
2320e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2321ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
23228d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2323ca15aa20SStefano Zampini   ierr = PetscArraycpy(x,aa+col*a->lda,A->rmap->n);CHKERRQ(ierr);
23248d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2325ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
23268d0534beSBarry Smith   PetscFunctionReturn(0);
23278d0534beSBarry Smith }
23288d0534beSBarry Smith 
232952c5f739Sprj- PETSC_INTERN PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
23300716a85fSBarry Smith {
23310716a85fSBarry Smith   PetscErrorCode    ierr;
23320716a85fSBarry Smith   PetscInt          i,j,m,n;
23331683a169SBarry Smith   const PetscScalar *a;
23340716a85fSBarry Smith 
23350716a85fSBarry Smith   PetscFunctionBegin;
23360716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2337580bdb30SBarry Smith   ierr = PetscArrayzero(norms,n);CHKERRQ(ierr);
23381683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&a);CHKERRQ(ierr);
23390716a85fSBarry Smith   if (type == NORM_2) {
23400716a85fSBarry Smith     for (i=0; i<n; i++) {
23410716a85fSBarry Smith       for (j=0; j<m; j++) {
23420716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
23430716a85fSBarry Smith       }
23440716a85fSBarry Smith       a += m;
23450716a85fSBarry Smith     }
23460716a85fSBarry Smith   } else if (type == NORM_1) {
23470716a85fSBarry Smith     for (i=0; i<n; i++) {
23480716a85fSBarry Smith       for (j=0; j<m; j++) {
23490716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
23500716a85fSBarry Smith       }
23510716a85fSBarry Smith       a += m;
23520716a85fSBarry Smith     }
23530716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
23540716a85fSBarry Smith     for (i=0; i<n; i++) {
23550716a85fSBarry Smith       for (j=0; j<m; j++) {
23560716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
23570716a85fSBarry Smith       }
23580716a85fSBarry Smith       a += m;
23590716a85fSBarry Smith     }
2360ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
23611683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&a);CHKERRQ(ierr);
23620716a85fSBarry Smith   if (type == NORM_2) {
23638f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
23640716a85fSBarry Smith   }
23650716a85fSBarry Smith   PetscFunctionReturn(0);
23660716a85fSBarry Smith }
23670716a85fSBarry Smith 
236873a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
236973a71a0fSBarry Smith {
237073a71a0fSBarry Smith   PetscErrorCode ierr;
237173a71a0fSBarry Smith   PetscScalar    *a;
2372*637a0070SStefano Zampini   PetscInt       lda,m,n,i,j;
237373a71a0fSBarry Smith 
237473a71a0fSBarry Smith   PetscFunctionBegin;
237573a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
2376*637a0070SStefano Zampini   ierr = MatDenseGetLDA(x,&lda);CHKERRQ(ierr);
23778c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
2378*637a0070SStefano Zampini   for (j=0; j<n; j++) {
2379*637a0070SStefano Zampini     for (i=0; i<m; i++) {
2380*637a0070SStefano Zampini       ierr = PetscRandomGetValue(rctx,a+j*lda+i);CHKERRQ(ierr);
2381*637a0070SStefano Zampini     }
238273a71a0fSBarry Smith   }
23838c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
238473a71a0fSBarry Smith   PetscFunctionReturn(0);
238573a71a0fSBarry Smith }
238673a71a0fSBarry Smith 
23873b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
23883b49f96aSBarry Smith {
23893b49f96aSBarry Smith   PetscFunctionBegin;
23903b49f96aSBarry Smith   *missing = PETSC_FALSE;
23913b49f96aSBarry Smith   PetscFunctionReturn(0);
23923b49f96aSBarry Smith }
239373a71a0fSBarry Smith 
2394ca15aa20SStefano Zampini /* vals is not const */
2395af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
239686aefd0dSHong Zhang {
2397ca15aa20SStefano Zampini   PetscErrorCode ierr;
239886aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2399ca15aa20SStefano Zampini   PetscScalar    *v;
240086aefd0dSHong Zhang 
240186aefd0dSHong Zhang   PetscFunctionBegin;
240286aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2403ca15aa20SStefano Zampini   ierr  = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2404ca15aa20SStefano Zampini   *vals = v+col*a->lda;
2405ca15aa20SStefano Zampini   ierr  = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
240686aefd0dSHong Zhang   PetscFunctionReturn(0);
240786aefd0dSHong Zhang }
240886aefd0dSHong Zhang 
2409af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
241086aefd0dSHong Zhang {
241186aefd0dSHong Zhang   PetscFunctionBegin;
241286aefd0dSHong Zhang   *vals = 0; /* user cannot accidently use the array later */
241386aefd0dSHong Zhang   PetscFunctionReturn(0);
241486aefd0dSHong Zhang }
2415abc3b08eSStefano Zampini 
2416289bc588SBarry Smith /* -------------------------------------------------------------------*/
2417a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2418905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2419905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2420905e6a2fSBarry Smith                                         MatMult_SeqDense,
242197304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
24227c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
24237c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2424db4efbfdSBarry Smith                                         0,
2425db4efbfdSBarry Smith                                         0,
2426db4efbfdSBarry Smith                                         0,
2427db4efbfdSBarry Smith                                 /* 10*/ 0,
2428905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2429905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
243041f059aeSBarry Smith                                         MatSOR_SeqDense,
2431ec8511deSBarry Smith                                         MatTranspose_SeqDense,
243297304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2433905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2434905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2435905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2436905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2437c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2438c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2439905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2440905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2441d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2442db4efbfdSBarry Smith                                         0,
2443db4efbfdSBarry Smith                                         0,
2444db4efbfdSBarry Smith                                         0,
2445db4efbfdSBarry Smith                                         0,
24464994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2447273d9f13SBarry Smith                                         0,
2448905e6a2fSBarry Smith                                         0,
244973a71a0fSBarry Smith                                         0,
245073a71a0fSBarry Smith                                         0,
2451d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2452a5ae1ecdSBarry Smith                                         0,
2453a5ae1ecdSBarry Smith                                         0,
2454a5ae1ecdSBarry Smith                                         0,
2455a5ae1ecdSBarry Smith                                         0,
2456d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
24577dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2458a5ae1ecdSBarry Smith                                         0,
24594b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2460a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2461d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2462a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
24637d68702bSBarry Smith                                         MatShift_Basic,
2464a5ae1ecdSBarry Smith                                         0,
24653f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
246673a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2467a5ae1ecdSBarry Smith                                         0,
2468a5ae1ecdSBarry Smith                                         0,
2469a5ae1ecdSBarry Smith                                         0,
2470a5ae1ecdSBarry Smith                                         0,
2471d519adbfSMatthew Knepley                                 /* 54*/ 0,
2472a5ae1ecdSBarry Smith                                         0,
2473a5ae1ecdSBarry Smith                                         0,
2474a5ae1ecdSBarry Smith                                         0,
2475a5ae1ecdSBarry Smith                                         0,
2476d519adbfSMatthew Knepley                                 /* 59*/ 0,
2477e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2478e03a110bSBarry Smith                                         MatView_SeqDense,
2479357abbc8SBarry Smith                                         0,
248097304618SKris Buschelman                                         0,
2481d519adbfSMatthew Knepley                                 /* 64*/ 0,
248297304618SKris Buschelman                                         0,
248397304618SKris Buschelman                                         0,
248497304618SKris Buschelman                                         0,
248597304618SKris Buschelman                                         0,
2486d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
248797304618SKris Buschelman                                         0,
248897304618SKris Buschelman                                         0,
248997304618SKris Buschelman                                         0,
249097304618SKris Buschelman                                         0,
2491d519adbfSMatthew Knepley                                 /* 74*/ 0,
249297304618SKris Buschelman                                         0,
249397304618SKris Buschelman                                         0,
249497304618SKris Buschelman                                         0,
249597304618SKris Buschelman                                         0,
2496d519adbfSMatthew Knepley                                 /* 79*/ 0,
249797304618SKris Buschelman                                         0,
249897304618SKris Buschelman                                         0,
249997304618SKris Buschelman                                         0,
25005bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2501*637a0070SStefano Zampini                                         MatIsSymmetric_SeqDense,
25021cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2503865e5f61SKris Buschelman                                         0,
2504865e5f61SKris Buschelman                                         0,
2505865e5f61SKris Buschelman                                         0,
25064222ddf1SHong Zhang                                 /* 89*/ 0,
25074222ddf1SHong Zhang                                         0,
2508a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
25094222ddf1SHong Zhang                                         0,
25104222ddf1SHong Zhang                                         0,
25114222ddf1SHong Zhang                                 /* 94*/ 0,
25124222ddf1SHong Zhang                                         0,
25134222ddf1SHong Zhang                                         0,
251469f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2515284134d9SBarry Smith                                         0,
25164222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
2517284134d9SBarry Smith                                         0,
2518284134d9SBarry Smith                                         0,
2519ba337c44SJed Brown                                         MatConjugate_SeqDense,
2520f73d5cc4SBarry Smith                                         0,
2521ba337c44SJed Brown                                 /*104*/ 0,
2522ba337c44SJed Brown                                         MatRealPart_SeqDense,
2523ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2524985db425SBarry Smith                                         0,
2525985db425SBarry Smith                                         0,
25268208b9aeSStefano Zampini                                 /*109*/ 0,
2527985db425SBarry Smith                                         0,
25288d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2529aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
25303b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2531aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2532aabbc4fbSShri Abhyankar                                         0,
2533aabbc4fbSShri Abhyankar                                         0,
2534aabbc4fbSShri Abhyankar                                         0,
2535aabbc4fbSShri Abhyankar                                         0,
2536aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2537aabbc4fbSShri Abhyankar                                         0,
2538aabbc4fbSShri Abhyankar                                         0,
25390716a85fSBarry Smith                                         0,
25400716a85fSBarry Smith                                         0,
25410716a85fSBarry Smith                                 /*124*/ 0,
25425df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
25435df89d91SHong Zhang                                         0,
25445df89d91SHong Zhang                                         0,
25455df89d91SHong Zhang                                         0,
25465df89d91SHong Zhang                                 /*129*/ 0,
25474222ddf1SHong Zhang                                         0,
25484222ddf1SHong Zhang                                         0,
254975648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
25503964eb88SJed Brown                                         0,
25513964eb88SJed Brown                                 /*134*/ 0,
25523964eb88SJed Brown                                         0,
25533964eb88SJed Brown                                         0,
25543964eb88SJed Brown                                         0,
25553964eb88SJed Brown                                         0,
25563964eb88SJed Brown                                 /*139*/ 0,
2557f9426fe0SMark Adams                                         0,
2558d528f656SJakub Kruzik                                         0,
2559d528f656SJakub Kruzik                                         0,
2560d528f656SJakub Kruzik                                         0,
25614222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
25624222ddf1SHong Zhang                                 /*145*/ 0,
25634222ddf1SHong Zhang                                         0,
25644222ddf1SHong Zhang                                         0
2565985db425SBarry Smith };
256690ace30eSBarry Smith 
25674b828684SBarry Smith /*@C
2568fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2569d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2570d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2571289bc588SBarry Smith 
2572d083f849SBarry Smith    Collective
2573db81eaa0SLois Curfman McInnes 
257420563c6bSBarry Smith    Input Parameters:
2575db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
25760c775827SLois Curfman McInnes .  m - number of rows
257718f449edSLois Curfman McInnes .  n - number of columns
25780298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2579dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
258020563c6bSBarry Smith 
258120563c6bSBarry Smith    Output Parameter:
258244cd7ae7SLois Curfman McInnes .  A - the matrix
258320563c6bSBarry Smith 
2584b259b22eSLois Curfman McInnes    Notes:
258518f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
258618f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
25870298fd71SBarry Smith    set data=NULL.
258818f449edSLois Curfman McInnes 
2589027ccd11SLois Curfman McInnes    Level: intermediate
2590027ccd11SLois Curfman McInnes 
259169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
259220563c6bSBarry Smith @*/
25937087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2594289bc588SBarry Smith {
2595dfbe8321SBarry Smith   PetscErrorCode ierr;
25963b2fbd54SBarry Smith 
25973a40ed3dSBarry Smith   PetscFunctionBegin;
2598f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2599f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2600273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2601273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2602273d9f13SBarry Smith   PetscFunctionReturn(0);
2603273d9f13SBarry Smith }
2604273d9f13SBarry Smith 
2605273d9f13SBarry Smith /*@C
2606273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2607273d9f13SBarry Smith 
2608d083f849SBarry Smith    Collective
2609273d9f13SBarry Smith 
2610273d9f13SBarry Smith    Input Parameters:
26111c4f3114SJed Brown +  B - the matrix
26120298fd71SBarry Smith -  data - the array (or NULL)
2613273d9f13SBarry Smith 
2614273d9f13SBarry Smith    Notes:
2615273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2616273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2617284134d9SBarry Smith    need not call this routine.
2618273d9f13SBarry Smith 
2619273d9f13SBarry Smith    Level: intermediate
2620273d9f13SBarry Smith 
262169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA()
2622867c911aSBarry Smith 
2623273d9f13SBarry Smith @*/
26247087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2625273d9f13SBarry Smith {
26264ac538c5SBarry Smith   PetscErrorCode ierr;
2627a23d5eceSKris Buschelman 
2628a23d5eceSKris Buschelman   PetscFunctionBegin;
26294ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2630a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2631a23d5eceSKris Buschelman }
2632a23d5eceSKris Buschelman 
26337087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2634a23d5eceSKris Buschelman {
2635273d9f13SBarry Smith   Mat_SeqDense   *b;
2636dfbe8321SBarry Smith   PetscErrorCode ierr;
2637273d9f13SBarry Smith 
2638273d9f13SBarry Smith   PetscFunctionBegin;
2639273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2640a868139aSShri Abhyankar 
264134ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
264234ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
264334ef9618SShri Abhyankar 
2644273d9f13SBarry Smith   b       = (Mat_SeqDense*)B->data;
264586d161a7SShri Abhyankar   b->Mmax = B->rmap->n;
264686d161a7SShri Abhyankar   b->Nmax = B->cmap->n;
264786d161a7SShri Abhyankar   if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n;
264886d161a7SShri Abhyankar 
2649220afb94SBarry Smith   ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr);
26509e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
26519e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2652e92229d0SSatish Balay     ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr);
26533bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
26542205254eSKarl Rupp 
26559e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2656273d9f13SBarry Smith   } else { /* user-allocated storage */
26579e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2658273d9f13SBarry Smith     b->v          = data;
2659273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2660273d9f13SBarry Smith   }
26610450473dSBarry Smith   B->assembled = PETSC_TRUE;
2662273d9f13SBarry Smith   PetscFunctionReturn(0);
2663273d9f13SBarry Smith }
2664273d9f13SBarry Smith 
266565b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2666cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
26678baccfbdSHong Zhang {
2668d77f618aSHong Zhang   Mat               mat_elemental;
2669d77f618aSHong Zhang   PetscErrorCode    ierr;
26701683a169SBarry Smith   const PetscScalar *array;
26711683a169SBarry Smith   PetscScalar       *v_colwise;
2672d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2673d77f618aSHong Zhang 
26748baccfbdSHong Zhang   PetscFunctionBegin;
2675d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
26761683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&array);CHKERRQ(ierr);
2677d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2678d77f618aSHong Zhang   k = 0;
2679d77f618aSHong Zhang   for (j=0; j<N; j++) {
2680d77f618aSHong Zhang     cols[j] = j;
2681d77f618aSHong Zhang     for (i=0; i<M; i++) {
2682d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2683d77f618aSHong Zhang     }
2684d77f618aSHong Zhang   }
2685d77f618aSHong Zhang   for (i=0; i<M; i++) {
2686d77f618aSHong Zhang     rows[i] = i;
2687d77f618aSHong Zhang   }
26881683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&array);CHKERRQ(ierr);
2689d77f618aSHong Zhang 
2690d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2691d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2692d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2693d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2694d77f618aSHong Zhang 
2695d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2696d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2697d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2698d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2699d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2700d77f618aSHong Zhang 
2701511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
270228be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2703d77f618aSHong Zhang   } else {
2704d77f618aSHong Zhang     *newmat = mat_elemental;
2705d77f618aSHong Zhang   }
27068baccfbdSHong Zhang   PetscFunctionReturn(0);
27078baccfbdSHong Zhang }
270865b80a83SHong Zhang #endif
27098baccfbdSHong Zhang 
27101b807ce4Svictorle /*@C
27111b807ce4Svictorle   MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array
27121b807ce4Svictorle 
27131b807ce4Svictorle   Input parameter:
27141b807ce4Svictorle + A - the matrix
27151b807ce4Svictorle - lda - the leading dimension
27161b807ce4Svictorle 
27171b807ce4Svictorle   Notes:
2718867c911aSBarry Smith   This routine is to be used in conjunction with MatSeqDenseSetPreallocation();
27191b807ce4Svictorle   it asserts that the preallocation has a leading dimension (the LDA parameter
27201b807ce4Svictorle   of Blas and Lapack fame) larger than M, the first dimension of the matrix.
27211b807ce4Svictorle 
27221b807ce4Svictorle   Level: intermediate
27231b807ce4Svictorle 
2724284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize()
2725867c911aSBarry Smith 
27261b807ce4Svictorle @*/
27277087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetLDA(Mat B,PetscInt lda)
27281b807ce4Svictorle {
27291b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
273021a2c019SBarry Smith 
27311b807ce4Svictorle   PetscFunctionBegin;
2732e32f2f54SBarry 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);
27331b807ce4Svictorle   b->lda       = lda;
273421a2c019SBarry Smith   b->changelda = PETSC_FALSE;
273521a2c019SBarry Smith   b->Mmax      = PetscMax(b->Mmax,lda);
27361b807ce4Svictorle   PetscFunctionReturn(0);
27371b807ce4Svictorle }
27381b807ce4Svictorle 
2739d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
2740d528f656SJakub Kruzik {
2741d528f656SJakub Kruzik   PetscErrorCode ierr;
2742d528f656SJakub Kruzik   PetscMPIInt    size;
2743d528f656SJakub Kruzik 
2744d528f656SJakub Kruzik   PetscFunctionBegin;
2745d528f656SJakub Kruzik   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2746d528f656SJakub Kruzik   if (size == 1) {
2747d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
2748d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
2749d528f656SJakub Kruzik     } else {
2750d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2751d528f656SJakub Kruzik     }
2752d528f656SJakub Kruzik   } else {
2753d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
2754d528f656SJakub Kruzik   }
2755d528f656SJakub Kruzik   PetscFunctionReturn(0);
2756d528f656SJakub Kruzik }
2757d528f656SJakub Kruzik 
27580bad9183SKris Buschelman /*MC
2759fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
27600bad9183SKris Buschelman 
27610bad9183SKris Buschelman    Options Database Keys:
27620bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
27630bad9183SKris Buschelman 
27640bad9183SKris Buschelman   Level: beginner
27650bad9183SKris Buschelman 
276689665df3SBarry Smith .seealso: MatCreateSeqDense()
276789665df3SBarry Smith 
27680bad9183SKris Buschelman M*/
2769ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
2770273d9f13SBarry Smith {
2771273d9f13SBarry Smith   Mat_SeqDense   *b;
2772dfbe8321SBarry Smith   PetscErrorCode ierr;
27737c334f02SBarry Smith   PetscMPIInt    size;
2774273d9f13SBarry Smith 
2775273d9f13SBarry Smith   PetscFunctionBegin;
2776ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
2777e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
277855659b69SBarry Smith 
2779b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
2780549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
278144cd7ae7SLois Curfman McInnes   B->data = (void*)b;
278218f449edSLois Curfman McInnes 
2783273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
27844e220ebcSLois Curfman McInnes 
278549a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
2786bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
27878572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2788d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
2789d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
27908572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2791715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2792bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
27938baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
27948baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
27958baccfbdSHong Zhang #endif
27962bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
27972bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA);CHKERRQ(ierr);
27984222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
27994222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
2800*637a0070SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
28014222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaijcusparse_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
28022bf066beSStefano Zampini #endif
2803bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
28044222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
28054222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
2806bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2807bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
28084222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
2809a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqbaij_seqdense_C",MatMatMultSymbolic_SeqBAIJ_SeqDense);CHKERRQ(ierr);
2810a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqbaij_seqdense_C",MatMatMultNumeric_SeqBAIJ_SeqDense);CHKERRQ(ierr);
28114222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
2812c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqsbaij_seqdense_C",MatMatMultSymbolic_SeqSBAIJ_SeqDense);CHKERRQ(ierr);
2813c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqsbaij_seqdense_C",MatMatMultNumeric_SeqSBAIJ_SeqDense);CHKERRQ(ierr);
28144099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijperm_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28154099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijperm_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2816e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijsell_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2817e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijsell_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
281896e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijmkl_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
281996e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijmkl_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
282052c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_nest_seqdense_C",MatMatMultSymbolic_Nest_Dense);CHKERRQ(ierr);
282152c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_nest_seqdense_C",MatMatMultNumeric_Nest_Dense);CHKERRQ(ierr);
282296e6d5c4SRichard Tran Mills 
28233bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28243bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
28254099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28264099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2827e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2828e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
282996e6d5c4SRichard Tran Mills 
283096e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
283196e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2832af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
2833af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
283417667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
28353a40ed3dSBarry Smith   PetscFunctionReturn(0);
2836289bc588SBarry Smith }
283786aefd0dSHong Zhang 
283886aefd0dSHong Zhang /*@C
2839af53bab2SHong 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.
284086aefd0dSHong Zhang 
284186aefd0dSHong Zhang    Not Collective
284286aefd0dSHong Zhang 
284386aefd0dSHong Zhang    Input Parameter:
284486aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
284586aefd0dSHong Zhang -  col - column index
284686aefd0dSHong Zhang 
284786aefd0dSHong Zhang    Output Parameter:
284886aefd0dSHong Zhang .  vals - pointer to the data
284986aefd0dSHong Zhang 
285086aefd0dSHong Zhang    Level: intermediate
285186aefd0dSHong Zhang 
285286aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
285386aefd0dSHong Zhang @*/
285486aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
285586aefd0dSHong Zhang {
285686aefd0dSHong Zhang   PetscErrorCode ierr;
285786aefd0dSHong Zhang 
285886aefd0dSHong Zhang   PetscFunctionBegin;
285986aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
286086aefd0dSHong Zhang   PetscFunctionReturn(0);
286186aefd0dSHong Zhang }
286286aefd0dSHong Zhang 
286386aefd0dSHong Zhang /*@C
286486aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
286586aefd0dSHong Zhang 
286686aefd0dSHong Zhang    Not Collective
286786aefd0dSHong Zhang 
286886aefd0dSHong Zhang    Input Parameter:
286986aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
287086aefd0dSHong Zhang 
287186aefd0dSHong Zhang    Output Parameter:
287286aefd0dSHong Zhang .  vals - pointer to the data
287386aefd0dSHong Zhang 
287486aefd0dSHong Zhang    Level: intermediate
287586aefd0dSHong Zhang 
287686aefd0dSHong Zhang .seealso: MatDenseGetColumn()
287786aefd0dSHong Zhang @*/
287886aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
287986aefd0dSHong Zhang {
288086aefd0dSHong Zhang   PetscErrorCode ierr;
288186aefd0dSHong Zhang 
288286aefd0dSHong Zhang   PetscFunctionBegin;
288386aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
288486aefd0dSHong Zhang   PetscFunctionReturn(0);
288586aefd0dSHong Zhang }
2886