xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 5aae2c7a20a4b66abfbf84daf10ee40366c74d20)
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;
1677a3c3d58SStefano Zampini   PetscBool      cisdense;
168abc3b08eSStefano Zampini   PetscErrorCode ierr;
169abc3b08eSStefano Zampini 
170abc3b08eSStefano Zampini   PetscFunctionBegin;
1714222ddf1SHong Zhang   ierr = MatSetSizes(C,P->cmap->n,P->cmap->n,P->cmap->N,P->cmap->N);CHKERRQ(ierr);
1727a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
1737a3c3d58SStefano Zampini   if (!cisdense) {
1747a3c3d58SStefano Zampini     PetscBool flg;
1757a3c3d58SStefano Zampini 
1767a3c3d58SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)P,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
1774222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
1787a3c3d58SStefano Zampini   }
1797a3c3d58SStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
1804222ddf1SHong Zhang   c    = (Mat_SeqDense*)C->data;
181ca15aa20SStefano Zampini   ierr = MatCreate(PetscObjectComm((PetscObject)A),&c->ptapwork);CHKERRQ(ierr);
182ca15aa20SStefano Zampini   ierr = MatSetSizes(c->ptapwork,A->rmap->n,P->cmap->n,A->rmap->N,P->cmap->N);CHKERRQ(ierr);
1837a3c3d58SStefano Zampini   ierr = MatSetType(c->ptapwork,((PetscObject)C)->type_name);CHKERRQ(ierr);
1847a3c3d58SStefano Zampini   ierr = MatSetUp(c->ptapwork);CHKERRQ(ierr);
185abc3b08eSStefano Zampini   PetscFunctionReturn(0);
186abc3b08eSStefano Zampini }
187abc3b08eSStefano Zampini 
188cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
189b49cda9fSStefano Zampini {
190a13144ffSStefano Zampini   Mat            B = NULL;
191b49cda9fSStefano Zampini   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
192b49cda9fSStefano Zampini   Mat_SeqDense   *b;
193b49cda9fSStefano Zampini   PetscErrorCode ierr;
194b49cda9fSStefano Zampini   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i;
195b49cda9fSStefano Zampini   MatScalar      *av=a->a;
196a13144ffSStefano Zampini   PetscBool      isseqdense;
197b49cda9fSStefano Zampini 
198b49cda9fSStefano Zampini   PetscFunctionBegin;
199a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
200a13144ffSStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense);CHKERRQ(ierr);
201a32993e3SJed Brown     if (!isseqdense) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type_name);
202a13144ffSStefano Zampini   }
203a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
204b49cda9fSStefano Zampini     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
205b49cda9fSStefano Zampini     ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
206b49cda9fSStefano Zampini     ierr = MatSetType(B,MATSEQDENSE);CHKERRQ(ierr);
207b49cda9fSStefano Zampini     ierr = MatSeqDenseSetPreallocation(B,NULL);CHKERRQ(ierr);
208b49cda9fSStefano Zampini     b    = (Mat_SeqDense*)(B->data);
209a13144ffSStefano Zampini   } else {
210a13144ffSStefano Zampini     b    = (Mat_SeqDense*)((*newmat)->data);
211580bdb30SBarry Smith     ierr = PetscArrayzero(b->v,m*n);CHKERRQ(ierr);
212a13144ffSStefano Zampini   }
213b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
214b49cda9fSStefano Zampini     PetscInt j;
215b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
216b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
217b49cda9fSStefano Zampini       aj++;
218b49cda9fSStefano Zampini       av++;
219b49cda9fSStefano Zampini     }
220b49cda9fSStefano Zampini     ai++;
221b49cda9fSStefano Zampini   }
222b49cda9fSStefano Zampini 
223511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
224a13144ffSStefano Zampini     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
225a13144ffSStefano Zampini     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22628be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
227b49cda9fSStefano Zampini   } else {
228a13144ffSStefano Zampini     if (B) *newmat = B;
229a13144ffSStefano Zampini     ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
230a13144ffSStefano Zampini     ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
231b49cda9fSStefano Zampini   }
232b49cda9fSStefano Zampini   PetscFunctionReturn(0);
233b49cda9fSStefano Zampini }
234b49cda9fSStefano Zampini 
235cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
2366a63e612SBarry Smith {
2376a63e612SBarry Smith   Mat            B;
2386a63e612SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2396a63e612SBarry Smith   PetscErrorCode ierr;
2409399e1b8SMatthew G. Knepley   PetscInt       i, j;
2419399e1b8SMatthew G. Knepley   PetscInt       *rows, *nnz;
2429399e1b8SMatthew G. Knepley   MatScalar      *aa = a->v, *vals;
2436a63e612SBarry Smith 
2446a63e612SBarry Smith   PetscFunctionBegin;
245ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
2466a63e612SBarry Smith   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
2476a63e612SBarry Smith   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
2489399e1b8SMatthew G. Knepley   ierr = PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals);CHKERRQ(ierr);
2499399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2509399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) ++nnz[i];
2516a63e612SBarry Smith     aa += a->lda;
2526a63e612SBarry Smith   }
2539399e1b8SMatthew G. Knepley   ierr = MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz);CHKERRQ(ierr);
2549399e1b8SMatthew G. Knepley   aa = a->v;
2559399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2569399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2579399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) {rows[numRows] = i; vals[numRows++] = aa[i];}
2589399e1b8SMatthew G. Knepley     ierr = MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr);
2599399e1b8SMatthew G. Knepley     aa  += a->lda;
2609399e1b8SMatthew G. Knepley   }
2619399e1b8SMatthew G. Knepley   ierr = PetscFree3(rows,nnz,vals);CHKERRQ(ierr);
2626a63e612SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2636a63e612SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2646a63e612SBarry Smith 
265511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
26628be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
2676a63e612SBarry Smith   } else {
2686a63e612SBarry Smith     *newmat = B;
2696a63e612SBarry Smith   }
2706a63e612SBarry Smith   PetscFunctionReturn(0);
2716a63e612SBarry Smith }
2726a63e612SBarry Smith 
273ca15aa20SStefano Zampini PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
2741987afe7SBarry Smith {
2751987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
276ca15aa20SStefano Zampini   const PetscScalar *xv;
277ca15aa20SStefano Zampini   PetscScalar       *yv;
2780805154bSBarry Smith   PetscBLASInt      N,m,ldax,lday,one = 1;
279efee365bSSatish Balay   PetscErrorCode    ierr;
2803a40ed3dSBarry Smith 
2813a40ed3dSBarry Smith   PetscFunctionBegin;
282ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(X,&xv);CHKERRQ(ierr);
283ca15aa20SStefano Zampini   ierr = MatDenseGetArray(Y,&yv);CHKERRQ(ierr);
284c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n*X->cmap->n,&N);CHKERRQ(ierr);
285c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n,&m);CHKERRQ(ierr);
286c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->lda,&ldax);CHKERRQ(ierr);
287c5df96a5SBarry Smith   ierr = PetscBLASIntCast(y->lda,&lday);CHKERRQ(ierr);
288a5ce6ee0Svictorle   if (ldax>m || lday>m) {
289ca15aa20SStefano Zampini     PetscInt j;
290ca15aa20SStefano Zampini 
291d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
292ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&alpha,xv+j*ldax,&one,yv+j*lday,&one));
293a5ce6ee0Svictorle     }
294a5ce6ee0Svictorle   } else {
295ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&alpha,xv,&one,yv,&one));
296a5ce6ee0Svictorle   }
297ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(X,&xv);CHKERRQ(ierr);
298ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(Y,&yv);CHKERRQ(ierr);
2990450473dSBarry Smith   ierr = PetscLogFlops(PetscMax(2*N-1,0));CHKERRQ(ierr);
3003a40ed3dSBarry Smith   PetscFunctionReturn(0);
3011987afe7SBarry Smith }
3021987afe7SBarry Smith 
303e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
304289bc588SBarry Smith {
305ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n*A->cmap->n;
3063a40ed3dSBarry Smith 
3073a40ed3dSBarry Smith   PetscFunctionBegin;
3084e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
309ca15aa20SStefano Zampini   info->nz_allocated      = N;
310ca15aa20SStefano Zampini   info->nz_used           = N;
311ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
312ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
3134e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3147adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3154e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3164e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3174e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3183a40ed3dSBarry Smith   PetscFunctionReturn(0);
319289bc588SBarry Smith }
320289bc588SBarry Smith 
321637a0070SStefano Zampini PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
32280cd9d93SLois Curfman McInnes {
323273d9f13SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
324ca15aa20SStefano Zampini   PetscScalar    *v;
325efee365bSSatish Balay   PetscErrorCode ierr;
326c5df96a5SBarry Smith   PetscBLASInt   one = 1,j,nz,lda;
32780cd9d93SLois Curfman McInnes 
3283a40ed3dSBarry Smith   PetscFunctionBegin;
329ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
330c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->lda,&lda);CHKERRQ(ierr);
331d0f46423SBarry Smith   if (lda>A->rmap->n) {
332c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n,&nz);CHKERRQ(ierr);
333d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
334ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v+j*lda,&one));
335a5ce6ee0Svictorle     }
336a5ce6ee0Svictorle   } else {
337c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz);CHKERRQ(ierr);
338ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v,&one));
339a5ce6ee0Svictorle   }
340efee365bSSatish Balay   ierr = PetscLogFlops(nz);CHKERRQ(ierr);
341ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
3423a40ed3dSBarry Smith   PetscFunctionReturn(0);
34380cd9d93SLois Curfman McInnes }
34480cd9d93SLois Curfman McInnes 
345e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3461cbb95d3SBarry Smith {
3471cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
348ca15aa20SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
349ca15aa20SStefano Zampini   const PetscScalar *v;
350ca15aa20SStefano Zampini   PetscErrorCode    ierr;
3511cbb95d3SBarry Smith 
3521cbb95d3SBarry Smith   PetscFunctionBegin;
3531cbb95d3SBarry Smith   *fl = PETSC_FALSE;
354d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
355ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
3561cbb95d3SBarry Smith   for (i=0; i<m; i++) {
357ca15aa20SStefano Zampini     for (j=i; j<m; j++) {
358637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) {
359637a0070SStefano Zampini         goto restore;
3601cbb95d3SBarry Smith       }
3611cbb95d3SBarry Smith     }
362637a0070SStefano Zampini   }
3631cbb95d3SBarry Smith   *fl  = PETSC_TRUE;
364637a0070SStefano Zampini restore:
365637a0070SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
366637a0070SStefano Zampini   PetscFunctionReturn(0);
367637a0070SStefano Zampini }
368637a0070SStefano Zampini 
369637a0070SStefano Zampini static PetscErrorCode MatIsSymmetric_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
370637a0070SStefano Zampini {
371637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
372637a0070SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
373637a0070SStefano Zampini   const PetscScalar *v;
374637a0070SStefano Zampini   PetscErrorCode    ierr;
375637a0070SStefano Zampini 
376637a0070SStefano Zampini   PetscFunctionBegin;
377637a0070SStefano Zampini   *fl = PETSC_FALSE;
378637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
379637a0070SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
380637a0070SStefano Zampini   for (i=0; i<m; i++) {
381637a0070SStefano Zampini     for (j=i; j<m; j++) {
382637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - v[j+i*N]) > rtol) {
383637a0070SStefano Zampini         goto restore;
384637a0070SStefano Zampini       }
385637a0070SStefano Zampini     }
386637a0070SStefano Zampini   }
387637a0070SStefano Zampini   *fl  = PETSC_TRUE;
388637a0070SStefano Zampini restore:
389637a0070SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
3901cbb95d3SBarry Smith   PetscFunctionReturn(0);
3911cbb95d3SBarry Smith }
3921cbb95d3SBarry Smith 
393ca15aa20SStefano Zampini PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
394b24902e0SBarry Smith {
395ca15aa20SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
396b24902e0SBarry Smith   PetscErrorCode ierr;
397b24902e0SBarry Smith   PetscInt       lda = (PetscInt)mat->lda,j,m;
398b24902e0SBarry Smith 
399b24902e0SBarry Smith   PetscFunctionBegin;
400aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr);
401aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr);
4020298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr);
403b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
404ca15aa20SStefano Zampini     const PetscScalar *av;
405ca15aa20SStefano Zampini     PetscScalar       *v;
406ca15aa20SStefano Zampini 
407ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
408ca15aa20SStefano Zampini     ierr = MatDenseGetArray(newi,&v);CHKERRQ(ierr);
409d0f46423SBarry Smith     if (lda>A->rmap->n) {
410d0f46423SBarry Smith       m = A->rmap->n;
411d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
412ca15aa20SStefano Zampini         ierr = PetscArraycpy(v+j*m,av+j*lda,m);CHKERRQ(ierr);
413b24902e0SBarry Smith       }
414b24902e0SBarry Smith     } else {
415ca15aa20SStefano Zampini       ierr = PetscArraycpy(v,av,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
416b24902e0SBarry Smith     }
417ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(newi,&v);CHKERRQ(ierr);
418ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
419b24902e0SBarry Smith   }
420b24902e0SBarry Smith   PetscFunctionReturn(0);
421b24902e0SBarry Smith }
422b24902e0SBarry Smith 
423ca15aa20SStefano Zampini PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
42402cad45dSBarry Smith {
4256849ba73SBarry Smith   PetscErrorCode ierr;
42602cad45dSBarry Smith 
4273a40ed3dSBarry Smith   PetscFunctionBegin;
428ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr);
429d0f46423SBarry Smith   ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4305c9eb25fSBarry Smith   ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
431719d5645SBarry Smith   ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr);
432b24902e0SBarry Smith   PetscFunctionReturn(0);
433b24902e0SBarry Smith }
434b24902e0SBarry Smith 
435e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
436289bc588SBarry Smith {
4374482741eSBarry Smith   MatFactorInfo  info;
438a093e273SMatthew Knepley   PetscErrorCode ierr;
4393a40ed3dSBarry Smith 
4403a40ed3dSBarry Smith   PetscFunctionBegin;
441c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
442ca15aa20SStefano Zampini   ierr = (*fact->ops->lufactor)(fact,0,0,&info);CHKERRQ(ierr);
4433a40ed3dSBarry Smith   PetscFunctionReturn(0);
444289bc588SBarry Smith }
4456ee01492SSatish Balay 
446e0877f53SBarry Smith static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy)
447289bc588SBarry Smith {
448c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
4496849ba73SBarry Smith   PetscErrorCode    ierr;
450f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
451f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
452c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
45367e560aaSBarry Smith 
4543a40ed3dSBarry Smith   PetscFunctionBegin;
455c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
456f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4571ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
458580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
459d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_LU) {
46000121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4618b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
46200121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
463e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
464d5f3da31SBarry Smith   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
465a49dc2a2SStefano Zampini     if (A->spd) {
46600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4678b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
46800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
469e32f2f54SBarry Smith       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
470a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
471a49dc2a2SStefano Zampini     } else if (A->hermitian) {
47200121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
473a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
47400121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
475a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
476a49dc2a2SStefano Zampini #endif
477a49dc2a2SStefano Zampini     } else { /* symmetric case */
47800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
479a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
48000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
481a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
482a49dc2a2SStefano Zampini     }
4832205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
484f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4851ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
486dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
4873a40ed3dSBarry Smith   PetscFunctionReturn(0);
488289bc588SBarry Smith }
4896ee01492SSatish Balay 
490e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X)
49185e2c93fSHong Zhang {
49285e2c93fSHong Zhang   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
49385e2c93fSHong Zhang   PetscErrorCode    ierr;
4941683a169SBarry Smith   const PetscScalar *b;
4951683a169SBarry Smith   PetscScalar       *x;
496efb80c78SLisandro Dalcin   PetscInt          n;
497783b601eSJed Brown   PetscBLASInt      nrhs,info,m;
49885e2c93fSHong Zhang 
49985e2c93fSHong Zhang   PetscFunctionBegin;
500c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
5010298fd71SBarry Smith   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
502c5df96a5SBarry Smith   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
5031683a169SBarry Smith   ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
5048c778c55SBarry Smith   ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr);
50585e2c93fSHong Zhang 
506580bdb30SBarry Smith   ierr = PetscArraycpy(x,b,m*nrhs);CHKERRQ(ierr);
50785e2c93fSHong Zhang 
50885e2c93fSHong Zhang   if (A->factortype == MAT_FACTOR_LU) {
50900121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5108b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
51100121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
51285e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
51385e2c93fSHong Zhang   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
514a49dc2a2SStefano Zampini     if (A->spd) {
51500121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5168b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
51700121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
51885e2c93fSHong Zhang       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
519a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
520a49dc2a2SStefano Zampini     } else if (A->hermitian) {
52100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
522a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
52300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
524a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
525a49dc2a2SStefano Zampini #endif
526a49dc2a2SStefano Zampini     } else { /* symmetric case */
52700121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
528a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
52900121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
530a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
531a49dc2a2SStefano Zampini     }
5322205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
53385e2c93fSHong Zhang 
5341683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
5358c778c55SBarry Smith   ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr);
53685e2c93fSHong Zhang   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
53785e2c93fSHong Zhang   PetscFunctionReturn(0);
53885e2c93fSHong Zhang }
53985e2c93fSHong Zhang 
54000121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
54100121966SStefano Zampini 
542e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
543da3a660dSBarry Smith {
544c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
545dfbe8321SBarry Smith   PetscErrorCode    ierr;
546f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
547f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
548c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
54967e560aaSBarry Smith 
5503a40ed3dSBarry Smith   PetscFunctionBegin;
551c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
552f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5531ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
554580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
5558208b9aeSStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
55600121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5578b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
55800121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
559e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve");
5608208b9aeSStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
561a49dc2a2SStefano Zampini     if (A->spd) {
56200121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
56300121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
56400121966SStefano Zampini #endif
56500121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5668b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
56700121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
56800121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
56900121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
57000121966SStefano Zampini #endif
571a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
572a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
573a49dc2a2SStefano Zampini     } else if (A->hermitian) {
57400121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
57500121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
57600121966SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
57700121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
57800121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
579ae7cfcebSSatish Balay #endif
580a49dc2a2SStefano Zampini     } else { /* symmetric case */
58100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
582a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
58300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
584a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
585da3a660dSBarry Smith     }
586a49dc2a2SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
587f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5881ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
589dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
5903a40ed3dSBarry Smith   PetscFunctionReturn(0);
591da3a660dSBarry Smith }
5926ee01492SSatish Balay 
593db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
594db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
595db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
596ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
597db4efbfdSBarry Smith {
598db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
599db4efbfdSBarry Smith   PetscErrorCode ierr;
600db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
601db4efbfdSBarry Smith 
602db4efbfdSBarry Smith   PetscFunctionBegin;
603c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
604c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
605db4efbfdSBarry Smith   if (!mat->pivots) {
6068208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
6073bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
608db4efbfdSBarry Smith   }
609db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
6108e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6118b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
6128e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
6138e57ea43SSatish Balay 
614e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
615e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
6168208b9aeSStefano Zampini 
617db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6188208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
619db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
620d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
621db4efbfdSBarry Smith 
622f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
623f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
624f6224b95SHong Zhang 
625dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
626db4efbfdSBarry Smith   PetscFunctionReturn(0);
627db4efbfdSBarry Smith }
628db4efbfdSBarry Smith 
629a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
630ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
631db4efbfdSBarry Smith {
632db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
633db4efbfdSBarry Smith   PetscErrorCode ierr;
634c5df96a5SBarry Smith   PetscBLASInt   info,n;
635db4efbfdSBarry Smith 
636db4efbfdSBarry Smith   PetscFunctionBegin;
637c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
638db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
639a49dc2a2SStefano Zampini   if (A->spd) {
64000121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6418b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
64200121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
643a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
644a49dc2a2SStefano Zampini   } else if (A->hermitian) {
645a49dc2a2SStefano Zampini     if (!mat->pivots) {
646a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
647a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
648a49dc2a2SStefano Zampini     }
649a49dc2a2SStefano Zampini     if (!mat->fwork) {
650a49dc2a2SStefano Zampini       PetscScalar dummy;
651a49dc2a2SStefano Zampini 
652a49dc2a2SStefano Zampini       mat->lfwork = -1;
65300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
654a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
65500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
656a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
657a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
658a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
659a49dc2a2SStefano Zampini     }
66000121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
661a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
66200121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
663a49dc2a2SStefano Zampini #endif
664a49dc2a2SStefano Zampini   } else { /* symmetric case */
665a49dc2a2SStefano Zampini     if (!mat->pivots) {
666a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
667a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
668a49dc2a2SStefano Zampini     }
669a49dc2a2SStefano Zampini     if (!mat->fwork) {
670a49dc2a2SStefano Zampini       PetscScalar dummy;
671a49dc2a2SStefano Zampini 
672a49dc2a2SStefano Zampini       mat->lfwork = -1;
67300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
674a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
67500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
676a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
677a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
678a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
679a49dc2a2SStefano Zampini     }
68000121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
681a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
68200121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
683a49dc2a2SStefano Zampini   }
684e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
6858208b9aeSStefano Zampini 
686db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6878208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
688db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
689d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
6902205254eSKarl Rupp 
691f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
692f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
693f6224b95SHong Zhang 
694eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
695db4efbfdSBarry Smith   PetscFunctionReturn(0);
696db4efbfdSBarry Smith }
697db4efbfdSBarry Smith 
698db4efbfdSBarry Smith 
6990481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
700db4efbfdSBarry Smith {
701db4efbfdSBarry Smith   PetscErrorCode ierr;
702db4efbfdSBarry Smith   MatFactorInfo  info;
703db4efbfdSBarry Smith 
704db4efbfdSBarry Smith   PetscFunctionBegin;
705db4efbfdSBarry Smith   info.fill = 1.0;
7062205254eSKarl Rupp 
707c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
708ca15aa20SStefano Zampini   ierr = (*fact->ops->choleskyfactor)(fact,0,&info);CHKERRQ(ierr);
709db4efbfdSBarry Smith   PetscFunctionReturn(0);
710db4efbfdSBarry Smith }
711db4efbfdSBarry Smith 
712ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
713db4efbfdSBarry Smith {
714db4efbfdSBarry Smith   PetscFunctionBegin;
715c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
7161bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
717719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
718bd443b22SStefano Zampini   fact->ops->solve                 = MatSolve_SeqDense;
719bd443b22SStefano Zampini   fact->ops->matsolve              = MatMatSolve_SeqDense;
720bd443b22SStefano Zampini   fact->ops->solvetranspose        = MatSolveTranspose_SeqDense;
721db4efbfdSBarry Smith   PetscFunctionReturn(0);
722db4efbfdSBarry Smith }
723db4efbfdSBarry Smith 
724ca15aa20SStefano Zampini PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
725db4efbfdSBarry Smith {
726db4efbfdSBarry Smith   PetscFunctionBegin;
727b66fe19dSMatthew G Knepley   fact->preallocated           = PETSC_TRUE;
728c3ef05f6SHong Zhang   fact->assembled              = PETSC_TRUE;
729719d5645SBarry Smith   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
730bd443b22SStefano Zampini   fact->ops->solve             = MatSolve_SeqDense;
731bd443b22SStefano Zampini   fact->ops->matsolve          = MatMatSolve_SeqDense;
732bd443b22SStefano Zampini   fact->ops->solvetranspose    = MatSolveTranspose_SeqDense;
733db4efbfdSBarry Smith   PetscFunctionReturn(0);
734db4efbfdSBarry Smith }
735db4efbfdSBarry Smith 
736ca15aa20SStefano Zampini /* uses LAPACK */
737cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
738db4efbfdSBarry Smith {
739db4efbfdSBarry Smith   PetscErrorCode ierr;
740db4efbfdSBarry Smith 
741db4efbfdSBarry Smith   PetscFunctionBegin;
742ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
743db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
744ca15aa20SStefano Zampini   ierr = MatSetType(*fact,MATDENSE);CHKERRQ(ierr);
745db4efbfdSBarry Smith   if (ftype == MAT_FACTOR_LU) {
746db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
747db4efbfdSBarry Smith   } else {
748db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
749db4efbfdSBarry Smith   }
750d5f3da31SBarry Smith   (*fact)->factortype = ftype;
75100c67f3bSHong Zhang 
75200c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
75300c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
754db4efbfdSBarry Smith   PetscFunctionReturn(0);
755db4efbfdSBarry Smith }
756db4efbfdSBarry Smith 
757289bc588SBarry Smith /* ------------------------------------------------------------------*/
758e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
759289bc588SBarry Smith {
760c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
761d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
762d9ca1df4SBarry Smith   const PetscScalar *b;
763dfbe8321SBarry Smith   PetscErrorCode    ierr;
764d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
765c5df96a5SBarry Smith   PetscBLASInt      o = 1,bm;
766289bc588SBarry Smith 
7673a40ed3dSBarry Smith   PetscFunctionBegin;
768ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
769c70f7ee4SJunchao Zhang   if (A->offloadmask == PETSC_OFFLOAD_GPU) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
770ca15aa20SStefano Zampini #endif
771422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
772c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
773289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
7743bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
7752dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
776289bc588SBarry Smith   }
7771ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
778d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
779b965ef7fSBarry Smith   its  = its*lits;
780e32f2f54SBarry 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);
781289bc588SBarry Smith   while (its--) {
782fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
783289bc588SBarry Smith       for (i=0; i<m; i++) {
7843bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
78555a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
786289bc588SBarry Smith       }
787289bc588SBarry Smith     }
788fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
789289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
7903bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
79155a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
792289bc588SBarry Smith       }
793289bc588SBarry Smith     }
794289bc588SBarry Smith   }
795d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
7961ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
7973a40ed3dSBarry Smith   PetscFunctionReturn(0);
798289bc588SBarry Smith }
799289bc588SBarry Smith 
800289bc588SBarry Smith /* -----------------------------------------------------------------*/
801ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
802289bc588SBarry Smith {
803c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
804d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
805d9ca1df4SBarry Smith   PetscScalar       *y;
806dfbe8321SBarry Smith   PetscErrorCode    ierr;
8070805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
808ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
8093a40ed3dSBarry Smith 
8103a40ed3dSBarry Smith   PetscFunctionBegin;
811c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
812c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
813d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8142bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
8155ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8165ac36cfcSBarry Smith     PetscBLASInt i;
8175ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
8185ac36cfcSBarry Smith   } else {
8198b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
8205ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
8215ac36cfcSBarry Smith   }
822d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8232bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
8243a40ed3dSBarry Smith   PetscFunctionReturn(0);
825289bc588SBarry Smith }
826800995b7SMatthew Knepley 
827ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
828289bc588SBarry Smith {
829c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
830d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
831dfbe8321SBarry Smith   PetscErrorCode    ierr;
8320805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
833d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
8343a40ed3dSBarry Smith 
8353a40ed3dSBarry Smith   PetscFunctionBegin;
836c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
837c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
838d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8392bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
8405ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8415ac36cfcSBarry Smith     PetscBLASInt i;
8425ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
8435ac36cfcSBarry Smith   } else {
8448b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
8455ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
8465ac36cfcSBarry Smith   }
847d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8482bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
8493a40ed3dSBarry Smith   PetscFunctionReturn(0);
850289bc588SBarry Smith }
8516ee01492SSatish Balay 
852ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
853289bc588SBarry Smith {
854c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
855d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
856d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
857dfbe8321SBarry Smith   PetscErrorCode    ierr;
8580805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
8593a40ed3dSBarry Smith 
8603a40ed3dSBarry Smith   PetscFunctionBegin;
861c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
862c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
863d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
864600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
865d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8661ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8678b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
868d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8691ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
870dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8713a40ed3dSBarry Smith   PetscFunctionReturn(0);
872289bc588SBarry Smith }
8736ee01492SSatish Balay 
874ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
875289bc588SBarry Smith {
876c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
877d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
878d9ca1df4SBarry Smith   PetscScalar       *y;
879dfbe8321SBarry Smith   PetscErrorCode    ierr;
8800805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
88187828ca2SBarry Smith   PetscScalar       _DOne=1.0;
8823a40ed3dSBarry Smith 
8833a40ed3dSBarry Smith   PetscFunctionBegin;
884c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
885c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
886d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
887600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
888d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8891ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8908b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
891d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8921ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
893dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8943a40ed3dSBarry Smith   PetscFunctionReturn(0);
895289bc588SBarry Smith }
896289bc588SBarry Smith 
897289bc588SBarry Smith /* -----------------------------------------------------------------*/
898e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
899289bc588SBarry Smith {
900c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
9016849ba73SBarry Smith   PetscErrorCode ierr;
90213f74950SBarry Smith   PetscInt       i;
90367e560aaSBarry Smith 
9043a40ed3dSBarry Smith   PetscFunctionBegin;
905d0f46423SBarry Smith   *ncols = A->cmap->n;
906289bc588SBarry Smith   if (cols) {
907854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
908d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
909289bc588SBarry Smith   }
910289bc588SBarry Smith   if (vals) {
911ca15aa20SStefano Zampini     const PetscScalar *v;
912ca15aa20SStefano Zampini 
913ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
914854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
915ca15aa20SStefano Zampini     v   += row;
916d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
917ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
918289bc588SBarry Smith   }
9193a40ed3dSBarry Smith   PetscFunctionReturn(0);
920289bc588SBarry Smith }
9216ee01492SSatish Balay 
922e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
923289bc588SBarry Smith {
924dfbe8321SBarry Smith   PetscErrorCode ierr;
9256e111a19SKarl Rupp 
926606d414cSSatish Balay   PetscFunctionBegin;
927606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
928606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
9293a40ed3dSBarry Smith   PetscFunctionReturn(0);
930289bc588SBarry Smith }
931289bc588SBarry Smith /* ----------------------------------------------------------------*/
932e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
933289bc588SBarry Smith {
934c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
935ca15aa20SStefano Zampini   PetscScalar      *av;
93613f74950SBarry Smith   PetscInt         i,j,idx=0;
937ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
938c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
939ca15aa20SStefano Zampini #endif
940ca15aa20SStefano Zampini   PetscErrorCode   ierr;
941d6dfbf8fSBarry Smith 
9423a40ed3dSBarry Smith   PetscFunctionBegin;
943ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&av);CHKERRQ(ierr);
944289bc588SBarry Smith   if (!mat->roworiented) {
945dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
946289bc588SBarry Smith       for (j=0; j<n; j++) {
947cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
948cf9c20a2SJed 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);
949289bc588SBarry Smith         for (i=0; i<m; i++) {
950cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
951cf9c20a2SJed 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);
952ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
953289bc588SBarry Smith         }
954289bc588SBarry Smith       }
9553a40ed3dSBarry Smith     } else {
956289bc588SBarry Smith       for (j=0; j<n; j++) {
957cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
958cf9c20a2SJed 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);
959289bc588SBarry Smith         for (i=0; i<m; i++) {
960cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
961cf9c20a2SJed 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);
962ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
963289bc588SBarry Smith         }
964289bc588SBarry Smith       }
965289bc588SBarry Smith     }
9663a40ed3dSBarry Smith   } else {
967dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
968e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
969cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
970cf9c20a2SJed 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);
971e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
972cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
973cf9c20a2SJed 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);
974ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
975e8d4e0b9SBarry Smith         }
976e8d4e0b9SBarry Smith       }
9773a40ed3dSBarry Smith     } else {
978289bc588SBarry Smith       for (i=0; i<m; i++) {
979cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
980cf9c20a2SJed 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);
981289bc588SBarry Smith         for (j=0; j<n; j++) {
982cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
983cf9c20a2SJed 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);
984ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
985289bc588SBarry Smith         }
986289bc588SBarry Smith       }
987289bc588SBarry Smith     }
988e8d4e0b9SBarry Smith   }
989ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
990ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
991c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
992c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
993ca15aa20SStefano Zampini #endif
994ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&av);CHKERRQ(ierr);
995ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
996c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
997ca15aa20SStefano Zampini #endif
9983a40ed3dSBarry Smith   PetscFunctionReturn(0);
999289bc588SBarry Smith }
1000e8d4e0b9SBarry Smith 
1001e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1002ae80bb75SLois Curfman McInnes {
1003ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1004ca15aa20SStefano Zampini   const PetscScalar *vv;
100513f74950SBarry Smith   PetscInt          i,j;
1006ca15aa20SStefano Zampini   PetscErrorCode    ierr;
1007ae80bb75SLois Curfman McInnes 
10083a40ed3dSBarry Smith   PetscFunctionBegin;
1009ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1010ae80bb75SLois Curfman McInnes   /* row-oriented output */
1011ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
101297e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1013e32f2f54SBarry 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);
1014ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
10156f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1016e32f2f54SBarry 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);
1017ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1018ae80bb75SLois Curfman McInnes     }
1019ae80bb75SLois Curfman McInnes   }
1020ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
10213a40ed3dSBarry Smith   PetscFunctionReturn(0);
1022ae80bb75SLois Curfman McInnes }
1023ae80bb75SLois Curfman McInnes 
1024289bc588SBarry Smith /* -----------------------------------------------------------------*/
1025289bc588SBarry Smith 
10268491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1027aabbc4fbSShri Abhyankar {
1028aabbc4fbSShri Abhyankar   PetscErrorCode    ierr;
10298491ab44SLisandro Dalcin   PetscBool         skipHeader;
10308491ab44SLisandro Dalcin   PetscViewerFormat format;
10318491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
10328491ab44SLisandro Dalcin   const PetscScalar *v;
10338491ab44SLisandro Dalcin   PetscScalar       *vwork;
1034aabbc4fbSShri Abhyankar 
1035aabbc4fbSShri Abhyankar   PetscFunctionBegin;
10368491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
10378491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
10388491ab44SLisandro Dalcin   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
10398491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1040aabbc4fbSShri Abhyankar 
10418491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
10428491ab44SLisandro Dalcin 
10438491ab44SLisandro Dalcin   /* write matrix header */
10448491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
10458491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
10468491ab44SLisandro Dalcin   if (!skipHeader) {ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);}
10478491ab44SLisandro Dalcin 
10488491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
10498491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
10508491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
10518491ab44SLisandro Dalcin     /* store row lengths for each row */
10528491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
10538491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
10548491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
10558491ab44SLisandro Dalcin     /* store column indices (zero start index) */
10568491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
10578491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
10588491ab44SLisandro Dalcin         iwork[k] = j;
10598491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
10608491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
10618491ab44SLisandro Dalcin   }
10628491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
10638491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
10648491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
10658491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
10668491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
10678491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
10688491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
10698491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
10708491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
10718491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
10728491ab44SLisandro Dalcin   PetscFunctionReturn(0);
10738491ab44SLisandro Dalcin }
10748491ab44SLisandro Dalcin 
10758491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
10768491ab44SLisandro Dalcin {
10778491ab44SLisandro Dalcin   PetscErrorCode ierr;
10788491ab44SLisandro Dalcin   PetscBool      skipHeader;
10798491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
10808491ab44SLisandro Dalcin   PetscInt       rows,cols;
10818491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
10828491ab44SLisandro Dalcin 
10838491ab44SLisandro Dalcin   PetscFunctionBegin;
10848491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
10858491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
10868491ab44SLisandro Dalcin 
10878491ab44SLisandro Dalcin   if (!skipHeader) {
10888491ab44SLisandro Dalcin     ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
10898491ab44SLisandro Dalcin     if (header[0] != MAT_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
10908491ab44SLisandro Dalcin     M = header[1]; N = header[2];
10918491ab44SLisandro Dalcin     if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M);
10928491ab44SLisandro Dalcin     if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N);
10938491ab44SLisandro Dalcin     nz = header[3];
10948491ab44SLisandro Dalcin     if (nz != MATRIX_BINARY_FORMAT_DENSE && nz < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %D in file",nz);
1095aabbc4fbSShri Abhyankar   } else {
10968491ab44SLisandro Dalcin     ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
10978491ab44SLisandro 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");
10988491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1099e6324fbbSBarry Smith   }
1100aabbc4fbSShri Abhyankar 
11018491ab44SLisandro Dalcin   /* setup global sizes if not set */
11028491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
11038491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
11048491ab44SLisandro Dalcin   ierr = MatSetUp(mat);CHKERRQ(ierr);
11058491ab44SLisandro Dalcin   /* check if global sizes are correct */
11068491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
11078491ab44SLisandro 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);
1108aabbc4fbSShri Abhyankar 
11098491ab44SLisandro Dalcin   ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
11108491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
11118491ab44SLisandro Dalcin   ierr = MatDenseGetArray(mat,&v);CHKERRQ(ierr);
11128491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
11138491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
11148491ab44SLisandro Dalcin     PetscInt nnz = m*N;
11158491ab44SLisandro Dalcin     /* read in matrix values */
11168491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&vwork);CHKERRQ(ierr);
11178491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
11188491ab44SLisandro Dalcin     /* store values in column major order */
11198491ab44SLisandro Dalcin     for (j=0; j<N; j++)
11208491ab44SLisandro Dalcin       for (i=0; i<m; i++)
11218491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
11228491ab44SLisandro Dalcin     ierr = PetscFree(vwork);CHKERRQ(ierr);
11238491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
11248491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
11258491ab44SLisandro Dalcin     /* read in row lengths */
11268491ab44SLisandro Dalcin     ierr = PetscMalloc1(m,&rlens);CHKERRQ(ierr);
11278491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
11288491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
11298491ab44SLisandro Dalcin     /* read in column indices and values */
11308491ab44SLisandro Dalcin     ierr = PetscMalloc2(nnz,&icols,nnz,&vwork);CHKERRQ(ierr);
11318491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
11328491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
11338491ab44SLisandro Dalcin     /* store values in column major order */
11348491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
11358491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
11368491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
11378491ab44SLisandro Dalcin     ierr = PetscFree(rlens);CHKERRQ(ierr);
11388491ab44SLisandro Dalcin     ierr = PetscFree2(icols,vwork);CHKERRQ(ierr);
1139aabbc4fbSShri Abhyankar   }
11408491ab44SLisandro Dalcin   ierr = MatDenseRestoreArray(mat,&v);CHKERRQ(ierr);
11418491ab44SLisandro Dalcin   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
11428491ab44SLisandro Dalcin   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1143aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1144aabbc4fbSShri Abhyankar }
1145aabbc4fbSShri Abhyankar 
1146eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1147eb91f321SVaclav Hapla {
1148eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1149eb91f321SVaclav Hapla   PetscErrorCode ierr;
1150eb91f321SVaclav Hapla 
1151eb91f321SVaclav Hapla   PetscFunctionBegin;
1152eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1153eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1154eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
1155eb91f321SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1156eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1157eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1158eb91f321SVaclav Hapla   if (isbinary) {
11598491ab44SLisandro Dalcin     ierr = MatLoad_Dense_Binary(newMat,viewer);CHKERRQ(ierr);
1160eb91f321SVaclav Hapla   } else if (ishdf5) {
1161eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
1162eb91f321SVaclav Hapla     ierr = MatLoad_Dense_HDF5(newMat,viewer);CHKERRQ(ierr);
1163eb91f321SVaclav Hapla #else
1164eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1165eb91f321SVaclav Hapla #endif
1166eb91f321SVaclav Hapla   } else {
1167eb91f321SVaclav 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);
1168eb91f321SVaclav Hapla   }
1169eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1170eb91f321SVaclav Hapla }
1171eb91f321SVaclav Hapla 
11726849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1173289bc588SBarry Smith {
1174932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1175dfbe8321SBarry Smith   PetscErrorCode    ierr;
117613f74950SBarry Smith   PetscInt          i,j;
11772dcb1b2aSMatthew Knepley   const char        *name;
1178ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1179f3ef73ceSBarry Smith   PetscViewerFormat format;
11805f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1181ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
11825f481a85SSatish Balay #endif
1183932b0c3eSLois Curfman McInnes 
11843a40ed3dSBarry Smith   PetscFunctionBegin;
1185ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1186b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1187456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
11883a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1189fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1190d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1191d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1192ca15aa20SStefano Zampini       v    = av + i;
119377431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1194d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1195aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1196329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
119757622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1198329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
119957622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
12006831982aSBarry Smith         }
120180cd9d93SLois Curfman McInnes #else
12026831982aSBarry Smith         if (*v) {
120357622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
12046831982aSBarry Smith         }
120580cd9d93SLois Curfman McInnes #endif
12061b807ce4Svictorle         v += a->lda;
120780cd9d93SLois Curfman McInnes       }
1208b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
120980cd9d93SLois Curfman McInnes     }
1210d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
12113a40ed3dSBarry Smith   } else {
1212d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1213aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
121447989497SBarry Smith     /* determine if matrix has all real values */
1215ca15aa20SStefano Zampini     v = av;
1216d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1217ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
121847989497SBarry Smith     }
121947989497SBarry Smith #endif
1220fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
12213a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1222d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1223d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1224fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1225ffac6cdbSBarry Smith     }
1226ffac6cdbSBarry Smith 
1227d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1228ca15aa20SStefano Zampini       v = av + i;
1229d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1230aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
123147989497SBarry Smith         if (allreal) {
1232c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
123347989497SBarry Smith         } else {
1234c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
123547989497SBarry Smith         }
1236289bc588SBarry Smith #else
1237c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1238289bc588SBarry Smith #endif
12391b807ce4Svictorle         v += a->lda;
1240289bc588SBarry Smith       }
1241b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1242289bc588SBarry Smith     }
1243fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1244b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1245ffac6cdbSBarry Smith     }
1246d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1247da3a660dSBarry Smith   }
1248ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1249b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
12503a40ed3dSBarry Smith   PetscFunctionReturn(0);
1251289bc588SBarry Smith }
1252289bc588SBarry Smith 
12539804daf3SBarry Smith #include <petscdraw.h>
1254e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1255f1af5d2fSBarry Smith {
1256f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
12576849ba73SBarry Smith   PetscErrorCode    ierr;
1258383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1259383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1260ca15aa20SStefano Zampini   const PetscScalar *v;
1261b0a32e0cSBarry Smith   PetscViewer       viewer;
1262b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1263f3ef73ceSBarry Smith   PetscViewerFormat format;
1264f1af5d2fSBarry Smith 
1265f1af5d2fSBarry Smith   PetscFunctionBegin;
1266f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1267b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1268b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1269f1af5d2fSBarry Smith 
1270f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1271ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1272fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1273383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1274f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1275f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1276383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1277f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1278f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1279f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1280ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1281ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1282ca15aa20SStefano Zampini         else continue;
1283b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1284f1af5d2fSBarry Smith       }
1285f1af5d2fSBarry Smith     }
1286383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1287f1af5d2fSBarry Smith   } else {
1288f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1289f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1290b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1291b05fc000SLisandro Dalcin     PetscDraw popup;
1292b05fc000SLisandro Dalcin 
1293f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1294f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1295f1af5d2fSBarry Smith     }
1296383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1297b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
129845f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1299383922c3SLisandro Dalcin 
1300383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1301f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1302f1af5d2fSBarry Smith       x_l = j;
1303f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1304f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1305f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1306f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1307b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1308b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1309f1af5d2fSBarry Smith       }
1310f1af5d2fSBarry Smith     }
1311383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1312f1af5d2fSBarry Smith   }
1313ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1314f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1315f1af5d2fSBarry Smith }
1316f1af5d2fSBarry Smith 
1317e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1318f1af5d2fSBarry Smith {
1319b0a32e0cSBarry Smith   PetscDraw      draw;
1320ace3abfcSBarry Smith   PetscBool      isnull;
1321329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1322dfbe8321SBarry Smith   PetscErrorCode ierr;
1323f1af5d2fSBarry Smith 
1324f1af5d2fSBarry Smith   PetscFunctionBegin;
1325b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1326b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1327abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1328f1af5d2fSBarry Smith 
1329d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1330f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1331b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1332832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1333b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
13340298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1335832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1336f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1337f1af5d2fSBarry Smith }
1338f1af5d2fSBarry Smith 
1339dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1340932b0c3eSLois Curfman McInnes {
1341dfbe8321SBarry Smith   PetscErrorCode ierr;
1342ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1343932b0c3eSLois Curfman McInnes 
13443a40ed3dSBarry Smith   PetscFunctionBegin;
1345251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1346251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1347251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
13480f5bd95cSBarry Smith 
1349c45a1595SBarry Smith   if (iascii) {
1350c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
13510f5bd95cSBarry Smith   } else if (isbinary) {
1352637a0070SStefano Zampini     ierr = MatView_Dense_Binary(A,viewer);CHKERRQ(ierr);
1353f1af5d2fSBarry Smith   } else if (isdraw) {
1354f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1355932b0c3eSLois Curfman McInnes   }
13563a40ed3dSBarry Smith   PetscFunctionReturn(0);
1357932b0c3eSLois Curfman McInnes }
1358289bc588SBarry Smith 
1359637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array)
1360d3042a70SBarry Smith {
1361d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1362d3042a70SBarry Smith 
1363d3042a70SBarry Smith   PetscFunctionBegin;
13646947451fSStefano Zampini   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec first");
1365d3042a70SBarry Smith   a->unplacedarray       = a->v;
1366d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1367d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1368637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1369ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1370c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1371ca15aa20SStefano Zampini #endif
1372d3042a70SBarry Smith   PetscFunctionReturn(0);
1373d3042a70SBarry Smith }
1374d3042a70SBarry Smith 
1375d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1376d3042a70SBarry Smith {
1377d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1378d3042a70SBarry Smith 
1379d3042a70SBarry Smith   PetscFunctionBegin;
13806947451fSStefano Zampini   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec first");
1381d3042a70SBarry Smith   a->v             = a->unplacedarray;
1382d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1383d3042a70SBarry Smith   a->unplacedarray = NULL;
1384ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1385c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1386ca15aa20SStefano Zampini #endif
1387d3042a70SBarry Smith   PetscFunctionReturn(0);
1388d3042a70SBarry Smith }
1389d3042a70SBarry Smith 
1390ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1391289bc588SBarry Smith {
1392ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1393dfbe8321SBarry Smith   PetscErrorCode ierr;
139490f02eecSBarry Smith 
13953a40ed3dSBarry Smith   PetscFunctionBegin;
1396aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1397d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1398a5a9c739SBarry Smith #endif
139905b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1400a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1401abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
14026857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1403637a0070SStefano Zampini   if (!l->unplaced_user_alloc) {ierr = PetscFree(l->unplacedarray);CHKERRQ(ierr);}
14046947451fSStefano Zampini   ierr = VecDestroy(&l->cvec);CHKERRQ(ierr);
1405bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1406dbd8c25aSHong Zhang 
1407dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
140849a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1409bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
141052c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
1411d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1412d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
141352c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL);CHKERRQ(ierr);
141452c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL);CHKERRQ(ierr);
14156947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayWrite_C",NULL);CHKERRQ(ierr);
14166947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayWrite_C",NULL);CHKERRQ(ierr);
14178baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
14188baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
14198baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
14208baccfbdSHong Zhang #endif
14212bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
14222bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL);CHKERRQ(ierr);
14234222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL);CHKERRQ(ierr);
14244222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL);CHKERRQ(ierr);
14254222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaijcusparse_seqdense_C",NULL);CHKERRQ(ierr);
14262bf066beSStefano Zampini #endif
1427bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
14284222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14294222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL);CHKERRQ(ierr);
1430bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1431bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14324222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1433a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1434a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
14354222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
1436c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
1437c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
143852c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
143952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
144052c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
144152c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
144252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
144352c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
144452c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_nest_seqdense_C",NULL);CHKERRQ(ierr);
144552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_nest_seqdense_C",NULL);CHKERRQ(ierr);
144652c5f739Sprj- 
14473bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14483bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
144952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
145052c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
145152c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
145252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
145352c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
145452c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
145586aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
145686aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
14576947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVec_C",NULL);CHKERRQ(ierr);
14586947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVec_C",NULL);CHKERRQ(ierr);
14596947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecRead_C",NULL);CHKERRQ(ierr);
14606947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecRead_C",NULL);CHKERRQ(ierr);
14616947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecWrite_C",NULL);CHKERRQ(ierr);
14626947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecWrite_C",NULL);CHKERRQ(ierr);
14633a40ed3dSBarry Smith   PetscFunctionReturn(0);
1464289bc588SBarry Smith }
1465289bc588SBarry Smith 
1466e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1467289bc588SBarry Smith {
1468c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
14696849ba73SBarry Smith   PetscErrorCode ierr;
147013f74950SBarry Smith   PetscInt       k,j,m,n,M;
147187828ca2SBarry Smith   PetscScalar    *v,tmp;
147248b35521SBarry Smith 
14733a40ed3dSBarry Smith   PetscFunctionBegin;
1474ca15aa20SStefano Zampini   m = A->rmap->n; M = mat->lda; n = A->cmap->n;
14752847e3fdSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX && m == n) { /* in place transpose */
1476ca15aa20SStefano Zampini     ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1477d3e5ee88SLois Curfman McInnes     for (j=0; j<m; j++) {
1478289bc588SBarry Smith       for (k=0; k<j; k++) {
14791b807ce4Svictorle         tmp        = v[j + k*M];
14801b807ce4Svictorle         v[j + k*M] = v[k + j*M];
14811b807ce4Svictorle         v[k + j*M] = tmp;
1482289bc588SBarry Smith       }
1483289bc588SBarry Smith     }
1484ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
14853a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1486d3e5ee88SLois Curfman McInnes     Mat          tmat;
1487ec8511deSBarry Smith     Mat_SeqDense *tmatd;
148887828ca2SBarry Smith     PetscScalar  *v2;
1489af36a384SStefano Zampini     PetscInt     M2;
1490ea709b57SSatish Balay 
14912847e3fdSStefano Zampini     if (reuse != MAT_REUSE_MATRIX) {
1492ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1493d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
14947adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
14950298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1496ca15aa20SStefano Zampini     } else tmat = *matout;
1497ca15aa20SStefano Zampini 
1498ca15aa20SStefano Zampini     ierr  = MatDenseGetArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
1499ca15aa20SStefano Zampini     ierr  = MatDenseGetArray(tmat,&v2);CHKERRQ(ierr);
1500ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1501ca15aa20SStefano Zampini     M2    = tmatd->lda;
1502d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1503af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1504d3e5ee88SLois Curfman McInnes     }
1505ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(tmat,&v2);CHKERRQ(ierr);
1506ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
15076d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15086d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15092847e3fdSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) *matout = tmat;
15102847e3fdSStefano Zampini     else {
15112847e3fdSStefano Zampini       ierr = MatHeaderMerge(A,&tmat);CHKERRQ(ierr);
15122847e3fdSStefano Zampini     }
151348b35521SBarry Smith   }
15143a40ed3dSBarry Smith   PetscFunctionReturn(0);
1515289bc588SBarry Smith }
1516289bc588SBarry Smith 
1517e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1518289bc588SBarry Smith {
1519c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1520c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1521ca15aa20SStefano Zampini   PetscInt          i;
1522ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
1523ca15aa20SStefano Zampini   PetscErrorCode    ierr;
15249ea5d5aeSSatish Balay 
15253a40ed3dSBarry Smith   PetscFunctionBegin;
1526d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1527d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1528ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A1,&v1);CHKERRQ(ierr);
1529ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A2,&v2);CHKERRQ(ierr);
1530ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
1531ca15aa20SStefano Zampini     ierr = PetscArraycmp(v1,v2,A1->rmap->n,flg);CHKERRQ(ierr);
1532ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1533ca15aa20SStefano Zampini     v1 += mat1->lda;
1534ca15aa20SStefano Zampini     v2 += mat2->lda;
15351b807ce4Svictorle   }
1536ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A1,&v1);CHKERRQ(ierr);
1537ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A2,&v2);CHKERRQ(ierr);
153877c4ece6SBarry Smith   *flg = PETSC_TRUE;
15393a40ed3dSBarry Smith   PetscFunctionReturn(0);
1540289bc588SBarry Smith }
1541289bc588SBarry Smith 
1542e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1543289bc588SBarry Smith {
1544c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
154513f74950SBarry Smith   PetscInt          i,n,len;
1546ca15aa20SStefano Zampini   PetscScalar       *x;
1547ca15aa20SStefano Zampini   const PetscScalar *vv;
1548ca15aa20SStefano Zampini   PetscErrorCode    ierr;
154944cd7ae7SLois Curfman McInnes 
15503a40ed3dSBarry Smith   PetscFunctionBegin;
15517a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
15521ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1553d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1554ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1555e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
155644cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1557ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1558289bc588SBarry Smith   }
1559ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
15601ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
15613a40ed3dSBarry Smith   PetscFunctionReturn(0);
1562289bc588SBarry Smith }
1563289bc588SBarry Smith 
1564e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1565289bc588SBarry Smith {
1566c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1567f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1568ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1569dfbe8321SBarry Smith   PetscErrorCode    ierr;
1570d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
157155659b69SBarry Smith 
15723a40ed3dSBarry Smith   PetscFunctionBegin;
1573ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&vv);CHKERRQ(ierr);
157428988994SBarry Smith   if (ll) {
15757a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1576f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1577e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1578da3a660dSBarry Smith     for (i=0; i<m; i++) {
1579da3a660dSBarry Smith       x = l[i];
1580ca15aa20SStefano Zampini       v = vv + i;
1581b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1582da3a660dSBarry Smith     }
1583f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1584eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1585da3a660dSBarry Smith   }
158628988994SBarry Smith   if (rr) {
15877a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1588f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1589e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1590da3a660dSBarry Smith     for (i=0; i<n; i++) {
1591da3a660dSBarry Smith       x = r[i];
1592ca15aa20SStefano Zampini       v = vv + i*mat->lda;
15932205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1594da3a660dSBarry Smith     }
1595f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1596eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1597da3a660dSBarry Smith   }
1598ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&vv);CHKERRQ(ierr);
15993a40ed3dSBarry Smith   PetscFunctionReturn(0);
1600289bc588SBarry Smith }
1601289bc588SBarry Smith 
1602ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1603289bc588SBarry Smith {
1604c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1605ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1606329f5518SBarry Smith   PetscReal         sum  = 0.0;
1607d0f46423SBarry Smith   PetscInt          lda  =mat->lda,m=A->rmap->n,i,j;
1608efee365bSSatish Balay   PetscErrorCode    ierr;
160955659b69SBarry Smith 
16103a40ed3dSBarry Smith   PetscFunctionBegin;
1611ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
1612ca15aa20SStefano Zampini   v    = vv;
1613289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1614a5ce6ee0Svictorle     if (lda>m) {
1615d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1616ca15aa20SStefano Zampini         v = vv+j*lda;
1617a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1618a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1619a5ce6ee0Svictorle         }
1620a5ce6ee0Svictorle       }
1621a5ce6ee0Svictorle     } else {
1622570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1623570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1624570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1625570b7f6dSBarry Smith     }
1626570b7f6dSBarry Smith #else
1627d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1628329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1629289bc588SBarry Smith       }
1630a5ce6ee0Svictorle     }
16318f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1632570b7f6dSBarry Smith #endif
1633dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16343a40ed3dSBarry Smith   } else if (type == NORM_1) {
1635064f8208SBarry Smith     *nrm = 0.0;
1636d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1637ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
1638289bc588SBarry Smith       sum = 0.0;
1639d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
164033a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1641289bc588SBarry Smith       }
1642064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1643289bc588SBarry Smith     }
1644eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16453a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1646064f8208SBarry Smith     *nrm = 0.0;
1647d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1648ca15aa20SStefano Zampini       v   = vv + j;
1649289bc588SBarry Smith       sum = 0.0;
1650d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
16511b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1652289bc588SBarry Smith       }
1653064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1654289bc588SBarry Smith     }
1655eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1656e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
1657ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
16583a40ed3dSBarry Smith   PetscFunctionReturn(0);
1659289bc588SBarry Smith }
1660289bc588SBarry Smith 
1661e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1662289bc588SBarry Smith {
1663c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
166463ba0a88SBarry Smith   PetscErrorCode ierr;
166567e560aaSBarry Smith 
16663a40ed3dSBarry Smith   PetscFunctionBegin;
1667b5a2b587SKris Buschelman   switch (op) {
1668b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
16694e0d8c25SBarry Smith     aij->roworiented = flg;
1670b5a2b587SKris Buschelman     break;
1671512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1672b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
16733971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
16744e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
167513fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1676b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1677b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
16780f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
16795021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
1680071fcb05SBarry Smith   case MAT_SORTED_FULL:
16815021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
16825021d80fSJed Brown     break;
16835021d80fSJed Brown   case MAT_SPD:
168477e54ba9SKris Buschelman   case MAT_SYMMETRIC:
168577e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
16869a4540c5SBarry Smith   case MAT_HERMITIAN:
16879a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
16885021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
168977e54ba9SKris Buschelman     break;
1690b5a2b587SKris Buschelman   default:
1691e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
16923a40ed3dSBarry Smith   }
16933a40ed3dSBarry Smith   PetscFunctionReturn(0);
1694289bc588SBarry Smith }
1695289bc588SBarry Smith 
1696e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
16976f0a148fSBarry Smith {
1698ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
16996849ba73SBarry Smith   PetscErrorCode ierr;
1700d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
1701ca15aa20SStefano Zampini   PetscScalar    *v;
17023a40ed3dSBarry Smith 
17033a40ed3dSBarry Smith   PetscFunctionBegin;
1704ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1705a5ce6ee0Svictorle   if (lda>m) {
1706d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1707ca15aa20SStefano Zampini       ierr = PetscArrayzero(v+j*lda,m);CHKERRQ(ierr);
1708a5ce6ee0Svictorle     }
1709a5ce6ee0Svictorle   } else {
1710ca15aa20SStefano Zampini     ierr = PetscArrayzero(v,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
1711a5ce6ee0Svictorle   }
1712ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17133a40ed3dSBarry Smith   PetscFunctionReturn(0);
17146f0a148fSBarry Smith }
17156f0a148fSBarry Smith 
1716e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
17176f0a148fSBarry Smith {
171897b48c8fSBarry Smith   PetscErrorCode    ierr;
1719ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1720b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
1721ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
172297b48c8fSBarry Smith   const PetscScalar *xx;
172355659b69SBarry Smith 
17243a40ed3dSBarry Smith   PetscFunctionBegin;
172576bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1726b9679d65SBarry Smith     for (i=0; i<N; i++) {
1727b9679d65SBarry Smith       if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1728b9679d65SBarry Smith       if (rows[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D requested to be zeroed greater than or equal number of rows %D",rows[i],A->rmap->n);
1729b9679d65SBarry Smith     }
173076bd3646SJed Brown   }
1731ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1732b9679d65SBarry Smith 
173397b48c8fSBarry Smith   /* fix right hand side if needed */
173497b48c8fSBarry Smith   if (x && b) {
173597b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
173697b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
17372205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
173897b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
173997b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
174097b48c8fSBarry Smith   }
174197b48c8fSBarry Smith 
1742ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
17436f0a148fSBarry Smith   for (i=0; i<N; i++) {
1744ca15aa20SStefano Zampini     slot = v + rows[i];
1745b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
17466f0a148fSBarry Smith   }
1747f4df32b1SMatthew Knepley   if (diag != 0.0) {
1748b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
17496f0a148fSBarry Smith     for (i=0; i<N; i++) {
1750ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1751f4df32b1SMatthew Knepley       *slot = diag;
17526f0a148fSBarry Smith     }
17536f0a148fSBarry Smith   }
1754ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17553a40ed3dSBarry Smith   PetscFunctionReturn(0);
17566f0a148fSBarry Smith }
1757557bce09SLois Curfman McInnes 
175849a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
175949a6ff4bSBarry Smith {
176049a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
176149a6ff4bSBarry Smith 
176249a6ff4bSBarry Smith   PetscFunctionBegin;
176349a6ff4bSBarry Smith   *lda = mat->lda;
176449a6ff4bSBarry Smith   PetscFunctionReturn(0);
176549a6ff4bSBarry Smith }
176649a6ff4bSBarry Smith 
1767637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array)
176864e87e97SBarry Smith {
1769c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
17703a40ed3dSBarry Smith 
17713a40ed3dSBarry Smith   PetscFunctionBegin;
177264e87e97SBarry Smith   *array = mat->v;
17733a40ed3dSBarry Smith   PetscFunctionReturn(0);
177464e87e97SBarry Smith }
17750754003eSLois Curfman McInnes 
1776637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array)
1777ff14e315SSatish Balay {
17783a40ed3dSBarry Smith   PetscFunctionBegin;
1779637a0070SStefano Zampini   *array = NULL;
17803a40ed3dSBarry Smith   PetscFunctionReturn(0);
1781ff14e315SSatish Balay }
17820754003eSLois Curfman McInnes 
1783dec5eb66SMatthew G Knepley /*@C
178449a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
178549a6ff4bSBarry Smith 
178649a6ff4bSBarry Smith    Logically Collective on Mat
178749a6ff4bSBarry Smith 
178849a6ff4bSBarry Smith    Input Parameter:
178949a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
179049a6ff4bSBarry Smith 
179149a6ff4bSBarry Smith    Output Parameter:
179249a6ff4bSBarry Smith .   lda - the leading dimension
179349a6ff4bSBarry Smith 
179449a6ff4bSBarry Smith    Level: intermediate
179549a6ff4bSBarry Smith 
179649a6ff4bSBarry Smith .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatSeqDenseSetLDA()
179749a6ff4bSBarry Smith @*/
179849a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
179949a6ff4bSBarry Smith {
180049a6ff4bSBarry Smith   PetscErrorCode ierr;
180149a6ff4bSBarry Smith 
180249a6ff4bSBarry Smith   PetscFunctionBegin;
180349a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
180449a6ff4bSBarry Smith   PetscFunctionReturn(0);
180549a6ff4bSBarry Smith }
180649a6ff4bSBarry Smith 
180749a6ff4bSBarry Smith /*@C
18086947451fSStefano Zampini    MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored
180973a71a0fSBarry Smith 
18108572280aSBarry Smith    Logically Collective on Mat
181173a71a0fSBarry Smith 
181273a71a0fSBarry Smith    Input Parameter:
18136947451fSStefano Zampini .  mat - a dense matrix
181473a71a0fSBarry Smith 
181573a71a0fSBarry Smith    Output Parameter:
181673a71a0fSBarry Smith .   array - pointer to the data
181773a71a0fSBarry Smith 
181873a71a0fSBarry Smith    Level: intermediate
181973a71a0fSBarry Smith 
18206947451fSStefano Zampini .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
182173a71a0fSBarry Smith @*/
18228c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
182373a71a0fSBarry Smith {
182473a71a0fSBarry Smith   PetscErrorCode ierr;
182573a71a0fSBarry Smith 
182673a71a0fSBarry Smith   PetscFunctionBegin;
18278c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
182873a71a0fSBarry Smith   PetscFunctionReturn(0);
182973a71a0fSBarry Smith }
183073a71a0fSBarry Smith 
1831dec5eb66SMatthew G Knepley /*@C
1832579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
183373a71a0fSBarry Smith 
18348572280aSBarry Smith    Logically Collective on Mat
18358572280aSBarry Smith 
18368572280aSBarry Smith    Input Parameters:
18376947451fSStefano Zampini +  mat - a dense matrix
1838a2b725a8SWilliam Gropp -  array - pointer to the data
18398572280aSBarry Smith 
18408572280aSBarry Smith    Level: intermediate
18418572280aSBarry Smith 
18426947451fSStefano Zampini .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
18438572280aSBarry Smith @*/
18448572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
18458572280aSBarry Smith {
18468572280aSBarry Smith   PetscErrorCode ierr;
18478572280aSBarry Smith 
18488572280aSBarry Smith   PetscFunctionBegin;
18498572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
18508572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
1851637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1852637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1853637a0070SStefano Zampini #endif
18548572280aSBarry Smith   PetscFunctionReturn(0);
18558572280aSBarry Smith }
18568572280aSBarry Smith 
18578572280aSBarry Smith /*@C
18586947451fSStefano Zampini    MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored
18598572280aSBarry Smith 
18608572280aSBarry Smith    Not Collective
18618572280aSBarry Smith 
18628572280aSBarry Smith    Input Parameter:
18636947451fSStefano Zampini .  mat - a dense matrix
18648572280aSBarry Smith 
18658572280aSBarry Smith    Output Parameter:
18668572280aSBarry Smith .   array - pointer to the data
18678572280aSBarry Smith 
18688572280aSBarry Smith    Level: intermediate
18698572280aSBarry Smith 
18706947451fSStefano Zampini .seealso: MatDenseRestoreArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
18718572280aSBarry Smith @*/
18728572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
18738572280aSBarry Smith {
18748572280aSBarry Smith   PetscErrorCode ierr;
18758572280aSBarry Smith 
18768572280aSBarry Smith   PetscFunctionBegin;
18778572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
18788572280aSBarry Smith   PetscFunctionReturn(0);
18798572280aSBarry Smith }
18808572280aSBarry Smith 
18818572280aSBarry Smith /*@C
18826947451fSStefano Zampini    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead()
18838572280aSBarry Smith 
188473a71a0fSBarry Smith    Not Collective
188573a71a0fSBarry Smith 
188673a71a0fSBarry Smith    Input Parameters:
18876947451fSStefano Zampini +  mat - a dense matrix
1888a2b725a8SWilliam Gropp -  array - pointer to the data
188973a71a0fSBarry Smith 
189073a71a0fSBarry Smith    Level: intermediate
189173a71a0fSBarry Smith 
18926947451fSStefano Zampini .seealso: MatDenseGetArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
189373a71a0fSBarry Smith @*/
18948572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
189573a71a0fSBarry Smith {
189673a71a0fSBarry Smith   PetscErrorCode ierr;
189773a71a0fSBarry Smith 
189873a71a0fSBarry Smith   PetscFunctionBegin;
18998572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
190073a71a0fSBarry Smith   PetscFunctionReturn(0);
190173a71a0fSBarry Smith }
190273a71a0fSBarry Smith 
19036947451fSStefano Zampini /*@C
19046947451fSStefano Zampini    MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored
19056947451fSStefano Zampini 
19066947451fSStefano Zampini    Not Collective
19076947451fSStefano Zampini 
19086947451fSStefano Zampini    Input Parameter:
19096947451fSStefano Zampini .  mat - a dense matrix
19106947451fSStefano Zampini 
19116947451fSStefano Zampini    Output Parameter:
19126947451fSStefano Zampini .   array - pointer to the data
19136947451fSStefano Zampini 
19146947451fSStefano Zampini    Level: intermediate
19156947451fSStefano Zampini 
19166947451fSStefano Zampini .seealso: MatDenseRestoreArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
19176947451fSStefano Zampini @*/
19186947451fSStefano Zampini PetscErrorCode  MatDenseGetArrayWrite(Mat A,PetscScalar **array)
19196947451fSStefano Zampini {
19206947451fSStefano Zampini   PetscErrorCode ierr;
19216947451fSStefano Zampini 
19226947451fSStefano Zampini   PetscFunctionBegin;
19236947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
19246947451fSStefano Zampini   PetscFunctionReturn(0);
19256947451fSStefano Zampini }
19266947451fSStefano Zampini 
19276947451fSStefano Zampini /*@C
19286947451fSStefano Zampini    MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite()
19296947451fSStefano Zampini 
19306947451fSStefano Zampini    Not Collective
19316947451fSStefano Zampini 
19326947451fSStefano Zampini    Input Parameters:
19336947451fSStefano Zampini +  mat - a dense matrix
19346947451fSStefano Zampini -  array - pointer to the data
19356947451fSStefano Zampini 
19366947451fSStefano Zampini    Level: intermediate
19376947451fSStefano Zampini 
19386947451fSStefano Zampini .seealso: MatDenseGetArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
19396947451fSStefano Zampini @*/
19406947451fSStefano Zampini PetscErrorCode  MatDenseRestoreArrayWrite(Mat A,PetscScalar **array)
19416947451fSStefano Zampini {
19426947451fSStefano Zampini   PetscErrorCode ierr;
19436947451fSStefano Zampini 
19446947451fSStefano Zampini   PetscFunctionBegin;
19456947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
19466947451fSStefano Zampini   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
19476947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
19486947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
19496947451fSStefano Zampini #endif
19506947451fSStefano Zampini   PetscFunctionReturn(0);
19516947451fSStefano Zampini }
19526947451fSStefano Zampini 
19537dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
19540754003eSLois Curfman McInnes {
1955c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
19566849ba73SBarry Smith   PetscErrorCode ierr;
1957ca15aa20SStefano Zampini   PetscInt       i,j,nrows,ncols,blda;
19585d0c19d7SBarry Smith   const PetscInt *irow,*icol;
195987828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
19600754003eSLois Curfman McInnes   Mat            newmat;
19610754003eSLois Curfman McInnes 
19623a40ed3dSBarry Smith   PetscFunctionBegin;
196378b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
196478b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1965e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1966e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
19670754003eSLois Curfman McInnes 
1968182d2002SSatish Balay   /* Check submatrixcall */
1969182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
197013f74950SBarry Smith     PetscInt n_cols,n_rows;
1971182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
197221a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
1973f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
1974c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
197521a2c019SBarry Smith     }
1976182d2002SSatish Balay     newmat = *B;
1977182d2002SSatish Balay   } else {
19780754003eSLois Curfman McInnes     /* Create and fill new matrix */
1979ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
1980f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
19817adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
19820298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1983182d2002SSatish Balay   }
1984182d2002SSatish Balay 
1985182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1986ca15aa20SStefano Zampini   ierr = MatDenseGetArray(newmat,&bv);CHKERRQ(ierr);
1987ca15aa20SStefano Zampini   ierr = MatDenseGetLDA(newmat,&blda);CHKERRQ(ierr);
1988182d2002SSatish Balay   for (i=0; i<ncols; i++) {
19896de62eeeSBarry Smith     av = v + mat->lda*icol[i];
1990ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
1991ca15aa20SStefano Zampini     bv += blda;
19920754003eSLois Curfman McInnes   }
1993ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(newmat,&bv);CHKERRQ(ierr);
1994182d2002SSatish Balay 
1995182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
19966d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19976d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19980754003eSLois Curfman McInnes 
19990754003eSLois Curfman McInnes   /* Free work space */
200078b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
200178b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2002182d2002SSatish Balay   *B   = newmat;
20033a40ed3dSBarry Smith   PetscFunctionReturn(0);
20040754003eSLois Curfman McInnes }
20050754003eSLois Curfman McInnes 
20067dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2007905e6a2fSBarry Smith {
20086849ba73SBarry Smith   PetscErrorCode ierr;
200913f74950SBarry Smith   PetscInt       i;
2010905e6a2fSBarry Smith 
20113a40ed3dSBarry Smith   PetscFunctionBegin;
2012905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2013df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
2014905e6a2fSBarry Smith   }
2015905e6a2fSBarry Smith 
2016905e6a2fSBarry Smith   for (i=0; i<n; i++) {
20177dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2018905e6a2fSBarry Smith   }
20193a40ed3dSBarry Smith   PetscFunctionReturn(0);
2020905e6a2fSBarry Smith }
2021905e6a2fSBarry Smith 
2022e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2023c0aa2d19SHong Zhang {
2024c0aa2d19SHong Zhang   PetscFunctionBegin;
2025c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2026c0aa2d19SHong Zhang }
2027c0aa2d19SHong Zhang 
2028e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2029c0aa2d19SHong Zhang {
2030c0aa2d19SHong Zhang   PetscFunctionBegin;
2031c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2032c0aa2d19SHong Zhang }
2033c0aa2d19SHong Zhang 
2034e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
20354b0e389bSBarry Smith {
20364b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
20376849ba73SBarry Smith   PetscErrorCode    ierr;
2038ca15aa20SStefano Zampini   const PetscScalar *va;
2039ca15aa20SStefano Zampini   PetscScalar       *vb;
2040d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
20413a40ed3dSBarry Smith 
20423a40ed3dSBarry Smith   PetscFunctionBegin;
204333f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
204433f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
2045cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
20463a40ed3dSBarry Smith     PetscFunctionReturn(0);
20473a40ed3dSBarry Smith   }
2048e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
2049ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&va);CHKERRQ(ierr);
2050ca15aa20SStefano Zampini   ierr = MatDenseGetArray(B,&vb);CHKERRQ(ierr);
2051a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
20520dbb7854Svictorle     for (j=0; j<n; j++) {
2053ca15aa20SStefano Zampini       ierr = PetscArraycpy(vb+j*lda2,va+j*lda1,m);CHKERRQ(ierr);
2054a5ce6ee0Svictorle     }
2055a5ce6ee0Svictorle   } else {
2056ca15aa20SStefano Zampini     ierr = PetscArraycpy(vb,va,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2057a5ce6ee0Svictorle   }
2058ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(B,&vb);CHKERRQ(ierr);
2059ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&va);CHKERRQ(ierr);
2060ca15aa20SStefano Zampini   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2061ca15aa20SStefano Zampini   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2062273d9f13SBarry Smith   PetscFunctionReturn(0);
2063273d9f13SBarry Smith }
2064273d9f13SBarry Smith 
2065e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
2066273d9f13SBarry Smith {
2067dfbe8321SBarry Smith   PetscErrorCode ierr;
2068273d9f13SBarry Smith 
2069273d9f13SBarry Smith   PetscFunctionBegin;
207018992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
207118992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
207218992e5dSStefano Zampini   if (!A->preallocated) {
2073273d9f13SBarry Smith     ierr = MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
207418992e5dSStefano Zampini   }
20753a40ed3dSBarry Smith   PetscFunctionReturn(0);
20764b0e389bSBarry Smith }
20774b0e389bSBarry Smith 
2078ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2079ba337c44SJed Brown {
2080ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2081ca15aa20SStefano Zampini   PetscScalar    *aa;
2082ca15aa20SStefano Zampini   PetscErrorCode ierr;
2083ba337c44SJed Brown 
2084ba337c44SJed Brown   PetscFunctionBegin;
2085ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2086ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2087ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2088ba337c44SJed Brown   PetscFunctionReturn(0);
2089ba337c44SJed Brown }
2090ba337c44SJed Brown 
2091ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2092ba337c44SJed Brown {
2093ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2094ca15aa20SStefano Zampini   PetscScalar    *aa;
2095ca15aa20SStefano Zampini   PetscErrorCode ierr;
2096ba337c44SJed Brown 
2097ba337c44SJed Brown   PetscFunctionBegin;
2098ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2099ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2100ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2101ba337c44SJed Brown   PetscFunctionReturn(0);
2102ba337c44SJed Brown }
2103ba337c44SJed Brown 
2104ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2105ba337c44SJed Brown {
2106ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2107ca15aa20SStefano Zampini   PetscScalar    *aa;
2108ca15aa20SStefano Zampini   PetscErrorCode ierr;
2109ba337c44SJed Brown 
2110ba337c44SJed Brown   PetscFunctionBegin;
2111ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2112ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
2113ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2114ba337c44SJed Brown   PetscFunctionReturn(0);
2115ba337c44SJed Brown }
2116284134d9SBarry Smith 
2117a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
21184222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2119a9fe9ddaSSatish Balay {
2120ee16a9a1SHong Zhang   PetscErrorCode ierr;
2121d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
21227a3c3d58SStefano Zampini   PetscBool      cisdense;
2123a9fe9ddaSSatish Balay 
2124ee16a9a1SHong Zhang   PetscFunctionBegin;
21254222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
21267a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
21277a3c3d58SStefano Zampini   if (!cisdense) {
21287a3c3d58SStefano Zampini     PetscBool flg;
21297a3c3d58SStefano Zampini 
2130ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
21314222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
21327a3c3d58SStefano Zampini   }
213318992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2134ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2135ee16a9a1SHong Zhang }
2136a9fe9ddaSSatish Balay 
2137a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2138a9fe9ddaSSatish Balay {
213952c5f739Sprj-   Mat_SeqDense       *a,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
21400805154bSBarry Smith   PetscBLASInt       m,n,k;
2141ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2142ca15aa20SStefano Zampini   PetscScalar       *cv;
2143a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2144fd4e9aacSBarry Smith   PetscBool         flg;
2145c2916339SPierre Jolivet   PetscErrorCode    (*numeric)(Mat,Mat,Mat)=NULL;
2146c2916339SPierre Jolivet   PetscErrorCode    ierr;
2147a9fe9ddaSSatish Balay 
2148a9fe9ddaSSatish Balay   PetscFunctionBegin;
2149fd4e9aacSBarry Smith   /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/
2150fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
2151c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqAIJ_SeqDense;
2152a001520aSPierre Jolivet   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQBAIJ,&flg);CHKERRQ(ierr);
2153c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqBAIJ_SeqDense;
2154c2916339SPierre Jolivet   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQSBAIJ,&flg);CHKERRQ(ierr);
2155c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqSBAIJ_SeqDense;
215652c5f739Sprj-   ierr = PetscObjectTypeCompare((PetscObject)A,MATNEST,&flg);CHKERRQ(ierr);
2157c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_Nest_Dense;
2158c2916339SPierre Jolivet   if (numeric) {
2159c2916339SPierre Jolivet     C->ops->matmultnumeric = numeric;
2160c2916339SPierre Jolivet     ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
216152c5f739Sprj-     PetscFunctionReturn(0);
216252c5f739Sprj-   }
216352c5f739Sprj-   a = (Mat_SeqDense*)A->data;
21648208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
21658208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2166c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
216749d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
2168ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
2169ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
2170ca15aa20SStefano Zampini   ierr = MatDenseGetArray(C,&cv);CHKERRQ(ierr);
2171ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
2172ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2173ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
2174ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
2175ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(C,&cv);CHKERRQ(ierr);
2176a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2177a9fe9ddaSSatish Balay }
2178a9fe9ddaSSatish Balay 
21794222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
218069f65d41SStefano Zampini {
218169f65d41SStefano Zampini   PetscErrorCode ierr;
218269f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
21837a3c3d58SStefano Zampini   PetscBool      cisdense;
218469f65d41SStefano Zampini 
218569f65d41SStefano Zampini   PetscFunctionBegin;
21864222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
21877a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
21887a3c3d58SStefano Zampini   if (!cisdense) {
21897a3c3d58SStefano Zampini     PetscBool flg;
21907a3c3d58SStefano Zampini 
2191ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
21924222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
21937a3c3d58SStefano Zampini   }
219418992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
219569f65d41SStefano Zampini   PetscFunctionReturn(0);
219669f65d41SStefano Zampini }
219769f65d41SStefano Zampini 
219869f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
219969f65d41SStefano Zampini {
220069f65d41SStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
220169f65d41SStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
220269f65d41SStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
220369f65d41SStefano Zampini   PetscBLASInt   m,n,k;
220469f65d41SStefano Zampini   PetscScalar    _DOne=1.0,_DZero=0.0;
220569f65d41SStefano Zampini   PetscErrorCode ierr;
220669f65d41SStefano Zampini 
220769f65d41SStefano Zampini   PetscFunctionBegin;
220849d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
220949d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
221069f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
221149d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
221269f65d41SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2213ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
221469f65d41SStefano Zampini   PetscFunctionReturn(0);
221569f65d41SStefano Zampini }
221669f65d41SStefano Zampini 
22174222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2218a9fe9ddaSSatish Balay {
2219ee16a9a1SHong Zhang   PetscErrorCode ierr;
2220d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
22217a3c3d58SStefano Zampini   PetscBool      cisdense;
2222a9fe9ddaSSatish Balay 
2223ee16a9a1SHong Zhang   PetscFunctionBegin;
22244222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
22257a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
22267a3c3d58SStefano Zampini   if (!cisdense) {
22277a3c3d58SStefano Zampini     PetscBool flg;
22287a3c3d58SStefano Zampini 
2229ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
22304222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
22317a3c3d58SStefano Zampini   }
223218992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2233ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2234ee16a9a1SHong Zhang }
2235a9fe9ddaSSatish Balay 
223675648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2237a9fe9ddaSSatish Balay {
2238a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2239a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2240a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
22410805154bSBarry Smith   PetscBLASInt   m,n,k;
2242a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
2243c5df96a5SBarry Smith   PetscErrorCode ierr;
2244a9fe9ddaSSatish Balay 
2245a9fe9ddaSSatish Balay   PetscFunctionBegin;
22468208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
22478208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2248c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
224949d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
22505ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2251ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2252a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2253a9fe9ddaSSatish Balay }
2254985db425SBarry Smith 
22554222ddf1SHong Zhang /* ----------------------------------------------- */
22564222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
22574222ddf1SHong Zhang {
22584222ddf1SHong Zhang   PetscFunctionBegin;
22594222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
22604222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
22614222ddf1SHong Zhang   /* dense mat may not call MatProductSymbolic(), thus set C->ops->productnumeric here */
22624222ddf1SHong Zhang   C->ops->productnumeric  = MatProductNumeric_AB;
22634222ddf1SHong Zhang   PetscFunctionReturn(0);
22644222ddf1SHong Zhang }
22654222ddf1SHong Zhang 
22664222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
22674222ddf1SHong Zhang {
22684222ddf1SHong Zhang   PetscFunctionBegin;
22694222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
22704222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
22714222ddf1SHong Zhang   C->ops->productnumeric           = MatProductNumeric_AtB;
22724222ddf1SHong Zhang   PetscFunctionReturn(0);
22734222ddf1SHong Zhang }
22744222ddf1SHong Zhang 
22754222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
22764222ddf1SHong Zhang {
22774222ddf1SHong Zhang   PetscFunctionBegin;
22784222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
22794222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
22804222ddf1SHong Zhang   C->ops->productnumeric           = MatProductNumeric_ABt;
22814222ddf1SHong Zhang   PetscFunctionReturn(0);
22824222ddf1SHong Zhang }
22834222ddf1SHong Zhang 
22844222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_PtAP(Mat C)
22854222ddf1SHong Zhang {
22864222ddf1SHong Zhang   PetscFunctionBegin;
22874222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_Basic;
22884222ddf1SHong Zhang   PetscFunctionReturn(0);
22894222ddf1SHong Zhang }
22904222ddf1SHong Zhang 
22914222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
22924222ddf1SHong Zhang {
22934222ddf1SHong Zhang   PetscErrorCode ierr;
22944222ddf1SHong Zhang   Mat_Product    *product = C->product;
22954222ddf1SHong Zhang 
22964222ddf1SHong Zhang   PetscFunctionBegin;
22974222ddf1SHong Zhang   switch (product->type) {
22984222ddf1SHong Zhang   case MATPRODUCT_AB:
22994222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AB(C);CHKERRQ(ierr);
23004222ddf1SHong Zhang     break;
23014222ddf1SHong Zhang   case MATPRODUCT_AtB:
23024222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AtB(C);CHKERRQ(ierr);
23034222ddf1SHong Zhang     break;
23044222ddf1SHong Zhang   case MATPRODUCT_ABt:
23054222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_ABt(C);CHKERRQ(ierr);
23064222ddf1SHong Zhang     break;
23074222ddf1SHong Zhang   case MATPRODUCT_PtAP:
2308*5aae2c7aSStefano Zampini   case MATPRODUCT_RARt:
23094222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_PtAP(C);CHKERRQ(ierr);
23104222ddf1SHong Zhang     break;
2311544a5e07SHong Zhang   default: SETERRQ1(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProduct type %s is not supported for SeqDense and SeqDense matrices",MatProductTypes[product->type]);
23124222ddf1SHong Zhang   }
23134222ddf1SHong Zhang   PetscFunctionReturn(0);
23144222ddf1SHong Zhang }
23154222ddf1SHong Zhang /* ----------------------------------------------- */
23164222ddf1SHong Zhang 
2317e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2318985db425SBarry Smith {
2319985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2320985db425SBarry Smith   PetscErrorCode     ierr;
2321d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2322985db425SBarry Smith   PetscScalar        *x;
2323ca15aa20SStefano Zampini   const PetscScalar *aa;
2324985db425SBarry Smith 
2325985db425SBarry Smith   PetscFunctionBegin;
2326e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2327985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2328985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2329ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2330e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2331985db425SBarry Smith   for (i=0; i<m; i++) {
2332985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2333985db425SBarry Smith     for (j=1; j<n; j++) {
2334ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2335985db425SBarry Smith     }
2336985db425SBarry Smith   }
2337ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2338985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2339985db425SBarry Smith   PetscFunctionReturn(0);
2340985db425SBarry Smith }
2341985db425SBarry Smith 
2342e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2343985db425SBarry Smith {
2344985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2345985db425SBarry Smith   PetscErrorCode    ierr;
2346d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2347985db425SBarry Smith   PetscScalar       *x;
2348985db425SBarry Smith   PetscReal         atmp;
2349ca15aa20SStefano Zampini   const PetscScalar *aa;
2350985db425SBarry Smith 
2351985db425SBarry Smith   PetscFunctionBegin;
2352e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2353985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2354985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2355ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2356e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2357985db425SBarry Smith   for (i=0; i<m; i++) {
23589189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2359985db425SBarry Smith     for (j=1; j<n; j++) {
2360ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2361985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2362985db425SBarry Smith     }
2363985db425SBarry Smith   }
2364ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2365985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2366985db425SBarry Smith   PetscFunctionReturn(0);
2367985db425SBarry Smith }
2368985db425SBarry Smith 
2369e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2370985db425SBarry Smith {
2371985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2372985db425SBarry Smith   PetscErrorCode    ierr;
2373d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2374985db425SBarry Smith   PetscScalar       *x;
2375ca15aa20SStefano Zampini   const PetscScalar *aa;
2376985db425SBarry Smith 
2377985db425SBarry Smith   PetscFunctionBegin;
2378e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2379ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2380985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2381985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2382e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2383985db425SBarry Smith   for (i=0; i<m; i++) {
2384985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2385985db425SBarry Smith     for (j=1; j<n; j++) {
2386ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2387985db425SBarry Smith     }
2388985db425SBarry Smith   }
2389985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2390ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2391985db425SBarry Smith   PetscFunctionReturn(0);
2392985db425SBarry Smith }
2393985db425SBarry Smith 
2394637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
23958d0534beSBarry Smith {
23968d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
23978d0534beSBarry Smith   PetscErrorCode    ierr;
23988d0534beSBarry Smith   PetscScalar       *x;
2399ca15aa20SStefano Zampini   const PetscScalar *aa;
24008d0534beSBarry Smith 
24018d0534beSBarry Smith   PetscFunctionBegin;
2402e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2403ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
24048d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2405ca15aa20SStefano Zampini   ierr = PetscArraycpy(x,aa+col*a->lda,A->rmap->n);CHKERRQ(ierr);
24068d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2407ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
24088d0534beSBarry Smith   PetscFunctionReturn(0);
24098d0534beSBarry Smith }
24108d0534beSBarry Smith 
241152c5f739Sprj- PETSC_INTERN PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
24120716a85fSBarry Smith {
24130716a85fSBarry Smith   PetscErrorCode    ierr;
24140716a85fSBarry Smith   PetscInt          i,j,m,n;
24151683a169SBarry Smith   const PetscScalar *a;
24160716a85fSBarry Smith 
24170716a85fSBarry Smith   PetscFunctionBegin;
24180716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2419580bdb30SBarry Smith   ierr = PetscArrayzero(norms,n);CHKERRQ(ierr);
24201683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&a);CHKERRQ(ierr);
24210716a85fSBarry Smith   if (type == NORM_2) {
24220716a85fSBarry Smith     for (i=0; i<n; i++) {
24230716a85fSBarry Smith       for (j=0; j<m; j++) {
24240716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
24250716a85fSBarry Smith       }
24260716a85fSBarry Smith       a += m;
24270716a85fSBarry Smith     }
24280716a85fSBarry Smith   } else if (type == NORM_1) {
24290716a85fSBarry Smith     for (i=0; i<n; i++) {
24300716a85fSBarry Smith       for (j=0; j<m; j++) {
24310716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
24320716a85fSBarry Smith       }
24330716a85fSBarry Smith       a += m;
24340716a85fSBarry Smith     }
24350716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
24360716a85fSBarry Smith     for (i=0; i<n; i++) {
24370716a85fSBarry Smith       for (j=0; j<m; j++) {
24380716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
24390716a85fSBarry Smith       }
24400716a85fSBarry Smith       a += m;
24410716a85fSBarry Smith     }
2442ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
24431683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&a);CHKERRQ(ierr);
24440716a85fSBarry Smith   if (type == NORM_2) {
24458f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
24460716a85fSBarry Smith   }
24470716a85fSBarry Smith   PetscFunctionReturn(0);
24480716a85fSBarry Smith }
24490716a85fSBarry Smith 
245073a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
245173a71a0fSBarry Smith {
245273a71a0fSBarry Smith   PetscErrorCode ierr;
245373a71a0fSBarry Smith   PetscScalar    *a;
2454637a0070SStefano Zampini   PetscInt       lda,m,n,i,j;
245573a71a0fSBarry Smith 
245673a71a0fSBarry Smith   PetscFunctionBegin;
245773a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
2458637a0070SStefano Zampini   ierr = MatDenseGetLDA(x,&lda);CHKERRQ(ierr);
24598c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
2460637a0070SStefano Zampini   for (j=0; j<n; j++) {
2461637a0070SStefano Zampini     for (i=0; i<m; i++) {
2462637a0070SStefano Zampini       ierr = PetscRandomGetValue(rctx,a+j*lda+i);CHKERRQ(ierr);
2463637a0070SStefano Zampini     }
246473a71a0fSBarry Smith   }
24658c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
246673a71a0fSBarry Smith   PetscFunctionReturn(0);
246773a71a0fSBarry Smith }
246873a71a0fSBarry Smith 
24693b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
24703b49f96aSBarry Smith {
24713b49f96aSBarry Smith   PetscFunctionBegin;
24723b49f96aSBarry Smith   *missing = PETSC_FALSE;
24733b49f96aSBarry Smith   PetscFunctionReturn(0);
24743b49f96aSBarry Smith }
247573a71a0fSBarry Smith 
2476ca15aa20SStefano Zampini /* vals is not const */
2477af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
247886aefd0dSHong Zhang {
2479ca15aa20SStefano Zampini   PetscErrorCode ierr;
248086aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2481ca15aa20SStefano Zampini   PetscScalar    *v;
248286aefd0dSHong Zhang 
248386aefd0dSHong Zhang   PetscFunctionBegin;
248486aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2485ca15aa20SStefano Zampini   ierr  = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2486ca15aa20SStefano Zampini   *vals = v+col*a->lda;
2487ca15aa20SStefano Zampini   ierr  = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
248886aefd0dSHong Zhang   PetscFunctionReturn(0);
248986aefd0dSHong Zhang }
249086aefd0dSHong Zhang 
2491af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
249286aefd0dSHong Zhang {
249386aefd0dSHong Zhang   PetscFunctionBegin;
249486aefd0dSHong Zhang   *vals = 0; /* user cannot accidently use the array later */
249586aefd0dSHong Zhang   PetscFunctionReturn(0);
249686aefd0dSHong Zhang }
2497abc3b08eSStefano Zampini 
2498289bc588SBarry Smith /* -------------------------------------------------------------------*/
2499a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2500905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2501905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2502905e6a2fSBarry Smith                                         MatMult_SeqDense,
250397304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
25047c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
25057c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2506db4efbfdSBarry Smith                                         0,
2507db4efbfdSBarry Smith                                         0,
2508db4efbfdSBarry Smith                                         0,
2509db4efbfdSBarry Smith                                 /* 10*/ 0,
2510905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2511905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
251241f059aeSBarry Smith                                         MatSOR_SeqDense,
2513ec8511deSBarry Smith                                         MatTranspose_SeqDense,
251497304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2515905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2516905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2517905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2518905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2519c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2520c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2521905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2522905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2523d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2524db4efbfdSBarry Smith                                         0,
2525db4efbfdSBarry Smith                                         0,
2526db4efbfdSBarry Smith                                         0,
2527db4efbfdSBarry Smith                                         0,
25284994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2529273d9f13SBarry Smith                                         0,
2530905e6a2fSBarry Smith                                         0,
253173a71a0fSBarry Smith                                         0,
253273a71a0fSBarry Smith                                         0,
2533d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2534a5ae1ecdSBarry Smith                                         0,
2535a5ae1ecdSBarry Smith                                         0,
2536a5ae1ecdSBarry Smith                                         0,
2537a5ae1ecdSBarry Smith                                         0,
2538d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
25397dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2540a5ae1ecdSBarry Smith                                         0,
25414b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2542a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2543d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2544a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
25457d68702bSBarry Smith                                         MatShift_Basic,
2546a5ae1ecdSBarry Smith                                         0,
25473f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
254873a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2549a5ae1ecdSBarry Smith                                         0,
2550a5ae1ecdSBarry Smith                                         0,
2551a5ae1ecdSBarry Smith                                         0,
2552a5ae1ecdSBarry Smith                                         0,
2553d519adbfSMatthew Knepley                                 /* 54*/ 0,
2554a5ae1ecdSBarry Smith                                         0,
2555a5ae1ecdSBarry Smith                                         0,
2556a5ae1ecdSBarry Smith                                         0,
2557a5ae1ecdSBarry Smith                                         0,
2558d519adbfSMatthew Knepley                                 /* 59*/ 0,
2559e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2560e03a110bSBarry Smith                                         MatView_SeqDense,
2561357abbc8SBarry Smith                                         0,
256297304618SKris Buschelman                                         0,
2563d519adbfSMatthew Knepley                                 /* 64*/ 0,
256497304618SKris Buschelman                                         0,
256597304618SKris Buschelman                                         0,
256697304618SKris Buschelman                                         0,
256797304618SKris Buschelman                                         0,
2568d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
256997304618SKris Buschelman                                         0,
257097304618SKris Buschelman                                         0,
257197304618SKris Buschelman                                         0,
257297304618SKris Buschelman                                         0,
2573d519adbfSMatthew Knepley                                 /* 74*/ 0,
257497304618SKris Buschelman                                         0,
257597304618SKris Buschelman                                         0,
257697304618SKris Buschelman                                         0,
257797304618SKris Buschelman                                         0,
2578d519adbfSMatthew Knepley                                 /* 79*/ 0,
257997304618SKris Buschelman                                         0,
258097304618SKris Buschelman                                         0,
258197304618SKris Buschelman                                         0,
25825bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2583637a0070SStefano Zampini                                         MatIsSymmetric_SeqDense,
25841cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2585865e5f61SKris Buschelman                                         0,
2586865e5f61SKris Buschelman                                         0,
2587865e5f61SKris Buschelman                                         0,
25884222ddf1SHong Zhang                                 /* 89*/ 0,
25894222ddf1SHong Zhang                                         0,
2590a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
25914222ddf1SHong Zhang                                         0,
25924222ddf1SHong Zhang                                         0,
25934222ddf1SHong Zhang                                 /* 94*/ 0,
25944222ddf1SHong Zhang                                         0,
25954222ddf1SHong Zhang                                         0,
259669f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2597284134d9SBarry Smith                                         0,
25984222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
2599284134d9SBarry Smith                                         0,
2600284134d9SBarry Smith                                         0,
2601ba337c44SJed Brown                                         MatConjugate_SeqDense,
2602f73d5cc4SBarry Smith                                         0,
2603ba337c44SJed Brown                                 /*104*/ 0,
2604ba337c44SJed Brown                                         MatRealPart_SeqDense,
2605ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2606985db425SBarry Smith                                         0,
2607985db425SBarry Smith                                         0,
26088208b9aeSStefano Zampini                                 /*109*/ 0,
2609985db425SBarry Smith                                         0,
26108d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2611aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
26123b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2613aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2614aabbc4fbSShri Abhyankar                                         0,
2615aabbc4fbSShri Abhyankar                                         0,
2616aabbc4fbSShri Abhyankar                                         0,
2617aabbc4fbSShri Abhyankar                                         0,
2618aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2619aabbc4fbSShri Abhyankar                                         0,
2620aabbc4fbSShri Abhyankar                                         0,
26210716a85fSBarry Smith                                         0,
26220716a85fSBarry Smith                                         0,
26230716a85fSBarry Smith                                 /*124*/ 0,
26245df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
26255df89d91SHong Zhang                                         0,
26265df89d91SHong Zhang                                         0,
26275df89d91SHong Zhang                                         0,
26285df89d91SHong Zhang                                 /*129*/ 0,
26294222ddf1SHong Zhang                                         0,
26304222ddf1SHong Zhang                                         0,
263175648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
26323964eb88SJed Brown                                         0,
26333964eb88SJed Brown                                 /*134*/ 0,
26343964eb88SJed Brown                                         0,
26353964eb88SJed Brown                                         0,
26363964eb88SJed Brown                                         0,
26373964eb88SJed Brown                                         0,
26383964eb88SJed Brown                                 /*139*/ 0,
2639f9426fe0SMark Adams                                         0,
2640d528f656SJakub Kruzik                                         0,
2641d528f656SJakub Kruzik                                         0,
2642d528f656SJakub Kruzik                                         0,
26434222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
26444222ddf1SHong Zhang                                 /*145*/ 0,
26454222ddf1SHong Zhang                                         0,
26464222ddf1SHong Zhang                                         0
2647985db425SBarry Smith };
264890ace30eSBarry Smith 
26494b828684SBarry Smith /*@C
2650fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2651d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2652d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2653289bc588SBarry Smith 
2654d083f849SBarry Smith    Collective
2655db81eaa0SLois Curfman McInnes 
265620563c6bSBarry Smith    Input Parameters:
2657db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
26580c775827SLois Curfman McInnes .  m - number of rows
265918f449edSLois Curfman McInnes .  n - number of columns
26600298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2661dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
266220563c6bSBarry Smith 
266320563c6bSBarry Smith    Output Parameter:
266444cd7ae7SLois Curfman McInnes .  A - the matrix
266520563c6bSBarry Smith 
2666b259b22eSLois Curfman McInnes    Notes:
266718f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
266818f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
26690298fd71SBarry Smith    set data=NULL.
267018f449edSLois Curfman McInnes 
2671027ccd11SLois Curfman McInnes    Level: intermediate
2672027ccd11SLois Curfman McInnes 
267369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
267420563c6bSBarry Smith @*/
26757087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2676289bc588SBarry Smith {
2677dfbe8321SBarry Smith   PetscErrorCode ierr;
26783b2fbd54SBarry Smith 
26793a40ed3dSBarry Smith   PetscFunctionBegin;
2680f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2681f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2682273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2683273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2684273d9f13SBarry Smith   PetscFunctionReturn(0);
2685273d9f13SBarry Smith }
2686273d9f13SBarry Smith 
2687273d9f13SBarry Smith /*@C
2688273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2689273d9f13SBarry Smith 
2690d083f849SBarry Smith    Collective
2691273d9f13SBarry Smith 
2692273d9f13SBarry Smith    Input Parameters:
26931c4f3114SJed Brown +  B - the matrix
26940298fd71SBarry Smith -  data - the array (or NULL)
2695273d9f13SBarry Smith 
2696273d9f13SBarry Smith    Notes:
2697273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2698273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2699284134d9SBarry Smith    need not call this routine.
2700273d9f13SBarry Smith 
2701273d9f13SBarry Smith    Level: intermediate
2702273d9f13SBarry Smith 
270369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA()
2704867c911aSBarry Smith 
2705273d9f13SBarry Smith @*/
27067087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2707273d9f13SBarry Smith {
27084ac538c5SBarry Smith   PetscErrorCode ierr;
2709a23d5eceSKris Buschelman 
2710a23d5eceSKris Buschelman   PetscFunctionBegin;
27114ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2712a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2713a23d5eceSKris Buschelman }
2714a23d5eceSKris Buschelman 
27157087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2716a23d5eceSKris Buschelman {
2717273d9f13SBarry Smith   Mat_SeqDense   *b;
2718dfbe8321SBarry Smith   PetscErrorCode ierr;
2719273d9f13SBarry Smith 
2720273d9f13SBarry Smith   PetscFunctionBegin;
2721273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2722a868139aSShri Abhyankar 
272334ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
272434ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
272534ef9618SShri Abhyankar 
2726273d9f13SBarry Smith   b       = (Mat_SeqDense*)B->data;
272786d161a7SShri Abhyankar   b->Mmax = B->rmap->n;
272886d161a7SShri Abhyankar   b->Nmax = B->cmap->n;
272986d161a7SShri Abhyankar   if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n;
273086d161a7SShri Abhyankar 
2731220afb94SBarry Smith   ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr);
27329e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
27339e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2734e92229d0SSatish Balay     ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr);
27353bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
27362205254eSKarl Rupp 
27379e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2738273d9f13SBarry Smith   } else { /* user-allocated storage */
27399e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2740273d9f13SBarry Smith     b->v          = data;
2741273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2742273d9f13SBarry Smith   }
27430450473dSBarry Smith   B->assembled = PETSC_TRUE;
2744273d9f13SBarry Smith   PetscFunctionReturn(0);
2745273d9f13SBarry Smith }
2746273d9f13SBarry Smith 
274765b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2748cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
27498baccfbdSHong Zhang {
2750d77f618aSHong Zhang   Mat               mat_elemental;
2751d77f618aSHong Zhang   PetscErrorCode    ierr;
27521683a169SBarry Smith   const PetscScalar *array;
27531683a169SBarry Smith   PetscScalar       *v_colwise;
2754d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2755d77f618aSHong Zhang 
27568baccfbdSHong Zhang   PetscFunctionBegin;
2757d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
27581683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&array);CHKERRQ(ierr);
2759d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2760d77f618aSHong Zhang   k = 0;
2761d77f618aSHong Zhang   for (j=0; j<N; j++) {
2762d77f618aSHong Zhang     cols[j] = j;
2763d77f618aSHong Zhang     for (i=0; i<M; i++) {
2764d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2765d77f618aSHong Zhang     }
2766d77f618aSHong Zhang   }
2767d77f618aSHong Zhang   for (i=0; i<M; i++) {
2768d77f618aSHong Zhang     rows[i] = i;
2769d77f618aSHong Zhang   }
27701683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&array);CHKERRQ(ierr);
2771d77f618aSHong Zhang 
2772d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2773d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2774d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2775d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2776d77f618aSHong Zhang 
2777d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2778d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2779d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2780d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2781d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2782d77f618aSHong Zhang 
2783511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
278428be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2785d77f618aSHong Zhang   } else {
2786d77f618aSHong Zhang     *newmat = mat_elemental;
2787d77f618aSHong Zhang   }
27888baccfbdSHong Zhang   PetscFunctionReturn(0);
27898baccfbdSHong Zhang }
279065b80a83SHong Zhang #endif
27918baccfbdSHong Zhang 
27921b807ce4Svictorle /*@C
27931b807ce4Svictorle   MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array
27941b807ce4Svictorle 
27951b807ce4Svictorle   Input parameter:
27961b807ce4Svictorle + A - the matrix
27971b807ce4Svictorle - lda - the leading dimension
27981b807ce4Svictorle 
27991b807ce4Svictorle   Notes:
2800867c911aSBarry Smith   This routine is to be used in conjunction with MatSeqDenseSetPreallocation();
28011b807ce4Svictorle   it asserts that the preallocation has a leading dimension (the LDA parameter
28021b807ce4Svictorle   of Blas and Lapack fame) larger than M, the first dimension of the matrix.
28031b807ce4Svictorle 
28041b807ce4Svictorle   Level: intermediate
28051b807ce4Svictorle 
2806284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize()
2807867c911aSBarry Smith 
28081b807ce4Svictorle @*/
28097087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetLDA(Mat B,PetscInt lda)
28101b807ce4Svictorle {
28111b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
281221a2c019SBarry Smith 
28131b807ce4Svictorle   PetscFunctionBegin;
2814e32f2f54SBarry 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);
28151b807ce4Svictorle   b->lda       = lda;
281621a2c019SBarry Smith   b->changelda = PETSC_FALSE;
281721a2c019SBarry Smith   b->Mmax      = PetscMax(b->Mmax,lda);
28181b807ce4Svictorle   PetscFunctionReturn(0);
28191b807ce4Svictorle }
28201b807ce4Svictorle 
2821d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
2822d528f656SJakub Kruzik {
2823d528f656SJakub Kruzik   PetscErrorCode ierr;
2824d528f656SJakub Kruzik   PetscMPIInt    size;
2825d528f656SJakub Kruzik 
2826d528f656SJakub Kruzik   PetscFunctionBegin;
2827d528f656SJakub Kruzik   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2828d528f656SJakub Kruzik   if (size == 1) {
2829d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
2830d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
2831d528f656SJakub Kruzik     } else {
2832d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2833d528f656SJakub Kruzik     }
2834d528f656SJakub Kruzik   } else {
2835d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
2836d528f656SJakub Kruzik   }
2837d528f656SJakub Kruzik   PetscFunctionReturn(0);
2838d528f656SJakub Kruzik }
2839d528f656SJakub Kruzik 
28406947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
28416947451fSStefano Zampini {
28426947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
28436947451fSStefano Zampini   PetscErrorCode ierr;
28446947451fSStefano Zampini 
28456947451fSStefano Zampini   PetscFunctionBegin;
28466947451fSStefano Zampini   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec first");
28476947451fSStefano Zampini   if (!a->cvec) {
28486947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
28496947451fSStefano Zampini   }
28506947451fSStefano Zampini   a->vecinuse = col + 1;
28516947451fSStefano Zampini   ierr = MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
28526947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
28536947451fSStefano Zampini   *v   = a->cvec;
28546947451fSStefano Zampini   PetscFunctionReturn(0);
28556947451fSStefano Zampini }
28566947451fSStefano Zampini 
28576947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
28586947451fSStefano Zampini {
28596947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
28606947451fSStefano Zampini   PetscErrorCode ierr;
28616947451fSStefano Zampini 
28626947451fSStefano Zampini   PetscFunctionBegin;
28636947451fSStefano Zampini   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec first");
28646947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
28656947451fSStefano Zampini   a->vecinuse = 0;
28666947451fSStefano Zampini   ierr = MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
28676947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
28686947451fSStefano Zampini   *v   = NULL;
28696947451fSStefano Zampini   PetscFunctionReturn(0);
28706947451fSStefano Zampini }
28716947451fSStefano Zampini 
28726947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
28736947451fSStefano Zampini {
28746947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
28756947451fSStefano Zampini   PetscErrorCode ierr;
28766947451fSStefano Zampini 
28776947451fSStefano Zampini   PetscFunctionBegin;
28786947451fSStefano Zampini   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec first");
28796947451fSStefano Zampini   if (!a->cvec) {
28806947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
28816947451fSStefano Zampini   }
28826947451fSStefano Zampini   a->vecinuse = col + 1;
28836947451fSStefano Zampini   ierr = MatDenseGetArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
28846947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
28856947451fSStefano Zampini   ierr = VecLockReadPush(a->cvec);CHKERRQ(ierr);
28866947451fSStefano Zampini   *v   = a->cvec;
28876947451fSStefano Zampini   PetscFunctionReturn(0);
28886947451fSStefano Zampini }
28896947451fSStefano Zampini 
28906947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
28916947451fSStefano Zampini {
28926947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
28936947451fSStefano Zampini   PetscErrorCode ierr;
28946947451fSStefano Zampini 
28956947451fSStefano Zampini   PetscFunctionBegin;
28966947451fSStefano Zampini   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec first");
28976947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
28986947451fSStefano Zampini   a->vecinuse = 0;
28996947451fSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
29006947451fSStefano Zampini   ierr = VecLockReadPop(a->cvec);CHKERRQ(ierr);
29016947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
29026947451fSStefano Zampini   *v   = NULL;
29036947451fSStefano Zampini   PetscFunctionReturn(0);
29046947451fSStefano Zampini }
29056947451fSStefano Zampini 
29066947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
29076947451fSStefano Zampini {
29086947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
29096947451fSStefano Zampini   PetscErrorCode ierr;
29106947451fSStefano Zampini 
29116947451fSStefano Zampini   PetscFunctionBegin;
29126947451fSStefano Zampini   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec first");
29136947451fSStefano Zampini   if (!a->cvec) {
29146947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
29156947451fSStefano Zampini   }
29166947451fSStefano Zampini   a->vecinuse = col + 1;
29176947451fSStefano Zampini   ierr = MatDenseGetArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
29186947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
29196947451fSStefano Zampini   *v   = a->cvec;
29206947451fSStefano Zampini   PetscFunctionReturn(0);
29216947451fSStefano Zampini }
29226947451fSStefano Zampini 
29236947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
29246947451fSStefano Zampini {
29256947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
29266947451fSStefano Zampini   PetscErrorCode ierr;
29276947451fSStefano Zampini 
29286947451fSStefano Zampini   PetscFunctionBegin;
29296947451fSStefano Zampini   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec first");
29306947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
29316947451fSStefano Zampini   a->vecinuse = 0;
29326947451fSStefano Zampini   ierr = MatDenseRestoreArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
29336947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
29346947451fSStefano Zampini   *v   = NULL;
29356947451fSStefano Zampini   PetscFunctionReturn(0);
29366947451fSStefano Zampini }
29376947451fSStefano Zampini 
29380bad9183SKris Buschelman /*MC
2939fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
29400bad9183SKris Buschelman 
29410bad9183SKris Buschelman    Options Database Keys:
29420bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
29430bad9183SKris Buschelman 
29440bad9183SKris Buschelman   Level: beginner
29450bad9183SKris Buschelman 
294689665df3SBarry Smith .seealso: MatCreateSeqDense()
294789665df3SBarry Smith 
29480bad9183SKris Buschelman M*/
2949ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
2950273d9f13SBarry Smith {
2951273d9f13SBarry Smith   Mat_SeqDense   *b;
2952dfbe8321SBarry Smith   PetscErrorCode ierr;
29537c334f02SBarry Smith   PetscMPIInt    size;
2954273d9f13SBarry Smith 
2955273d9f13SBarry Smith   PetscFunctionBegin;
2956ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
2957e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
295855659b69SBarry Smith 
2959b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
2960549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
296144cd7ae7SLois Curfman McInnes   B->data = (void*)b;
296218f449edSLois Curfman McInnes 
2963273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
29644e220ebcSLois Curfman McInnes 
296549a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
2966bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
29678572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2968d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
2969d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
29708572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2971715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
29726947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayWrite_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
29736947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayWrite_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2974bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
29758baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
29768baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
29778baccfbdSHong Zhang #endif
29782bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
29792bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA);CHKERRQ(ierr);
29804222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
29814222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
2982637a0070SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
29834222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaijcusparse_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
29842bf066beSStefano Zampini #endif
2985bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
29864222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
29874222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
2988bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2989bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
29904222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
2991a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqbaij_seqdense_C",MatMatMultSymbolic_SeqBAIJ_SeqDense);CHKERRQ(ierr);
2992a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqbaij_seqdense_C",MatMatMultNumeric_SeqBAIJ_SeqDense);CHKERRQ(ierr);
29934222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
2994c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqsbaij_seqdense_C",MatMatMultSymbolic_SeqSBAIJ_SeqDense);CHKERRQ(ierr);
2995c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqsbaij_seqdense_C",MatMatMultNumeric_SeqSBAIJ_SeqDense);CHKERRQ(ierr);
29964099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijperm_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
29974099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijperm_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2998e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijsell_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2999e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijsell_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
300096e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijmkl_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
300196e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijmkl_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
300252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_nest_seqdense_C",MatMatMultSymbolic_Nest_Dense);CHKERRQ(ierr);
300352c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_nest_seqdense_C",MatMatMultNumeric_Nest_Dense);CHKERRQ(ierr);
300496e6d5c4SRichard Tran Mills 
30053bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
30063bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
30074099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
30084099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
3009e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
3010e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
301196e6d5c4SRichard Tran Mills 
301296e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
301396e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
3014af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
3015af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
30166947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVec_C",MatDenseGetColumnVec_SeqDense);CHKERRQ(ierr);
30176947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVec_C",MatDenseRestoreColumnVec_SeqDense);CHKERRQ(ierr);
30186947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecRead_C",MatDenseGetColumnVecRead_SeqDense);CHKERRQ(ierr);
30196947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecRead_C",MatDenseRestoreColumnVecRead_SeqDense);CHKERRQ(ierr);
30206947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecWrite_C",MatDenseGetColumnVecWrite_SeqDense);CHKERRQ(ierr);
30216947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecWrite_C",MatDenseRestoreColumnVecWrite_SeqDense);CHKERRQ(ierr);
302217667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
30233a40ed3dSBarry Smith   PetscFunctionReturn(0);
3024289bc588SBarry Smith }
302586aefd0dSHong Zhang 
302686aefd0dSHong Zhang /*@C
3027af53bab2SHong 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.
302886aefd0dSHong Zhang 
302986aefd0dSHong Zhang    Not Collective
303086aefd0dSHong Zhang 
303186aefd0dSHong Zhang    Input Parameter:
303286aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
303386aefd0dSHong Zhang -  col - column index
303486aefd0dSHong Zhang 
303586aefd0dSHong Zhang    Output Parameter:
303686aefd0dSHong Zhang .  vals - pointer to the data
303786aefd0dSHong Zhang 
303886aefd0dSHong Zhang    Level: intermediate
303986aefd0dSHong Zhang 
304086aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
304186aefd0dSHong Zhang @*/
304286aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
304386aefd0dSHong Zhang {
304486aefd0dSHong Zhang   PetscErrorCode ierr;
304586aefd0dSHong Zhang 
304686aefd0dSHong Zhang   PetscFunctionBegin;
304786aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
304886aefd0dSHong Zhang   PetscFunctionReturn(0);
304986aefd0dSHong Zhang }
305086aefd0dSHong Zhang 
305186aefd0dSHong Zhang /*@C
305286aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
305386aefd0dSHong Zhang 
305486aefd0dSHong Zhang    Not Collective
305586aefd0dSHong Zhang 
305686aefd0dSHong Zhang    Input Parameter:
305786aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
305886aefd0dSHong Zhang 
305986aefd0dSHong Zhang    Output Parameter:
306086aefd0dSHong Zhang .  vals - pointer to the data
306186aefd0dSHong Zhang 
306286aefd0dSHong Zhang    Level: intermediate
306386aefd0dSHong Zhang 
306486aefd0dSHong Zhang .seealso: MatDenseGetColumn()
306586aefd0dSHong Zhang @*/
306686aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
306786aefd0dSHong Zhang {
306886aefd0dSHong Zhang   PetscErrorCode ierr;
306986aefd0dSHong Zhang 
307086aefd0dSHong Zhang   PetscFunctionBegin;
307186aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
307286aefd0dSHong Zhang   PetscFunctionReturn(0);
307386aefd0dSHong Zhang }
30746947451fSStefano Zampini 
30756947451fSStefano Zampini /*@C
30766947451fSStefano Zampini    MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec.
30776947451fSStefano Zampini 
30786947451fSStefano Zampini    Collective
30796947451fSStefano Zampini 
30806947451fSStefano Zampini    Input Parameter:
30816947451fSStefano Zampini +  mat - the Mat object
30826947451fSStefano Zampini -  col - the column index
30836947451fSStefano Zampini 
30846947451fSStefano Zampini    Output Parameter:
30856947451fSStefano Zampini .  v - the vector
30866947451fSStefano Zampini 
30876947451fSStefano Zampini    Notes:
30886947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed.
30896947451fSStefano Zampini      Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access.
30906947451fSStefano Zampini 
30916947451fSStefano Zampini    Level: intermediate
30926947451fSStefano Zampini 
30936947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
30946947451fSStefano Zampini @*/
30956947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec(Mat A,PetscInt col,Vec *v)
30966947451fSStefano Zampini {
30976947451fSStefano Zampini   PetscErrorCode ierr;
30986947451fSStefano Zampini 
30996947451fSStefano Zampini   PetscFunctionBegin;
31006947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
31016947451fSStefano Zampini   PetscValidType(A,1);
31026947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
31036947451fSStefano Zampini   PetscValidPointer(v,3);
31046947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
31056947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
31066947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
31076947451fSStefano Zampini   PetscFunctionReturn(0);
31086947451fSStefano Zampini }
31096947451fSStefano Zampini 
31106947451fSStefano Zampini /*@C
31116947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
31126947451fSStefano Zampini 
31136947451fSStefano Zampini    Collective
31146947451fSStefano Zampini 
31156947451fSStefano Zampini    Input Parameter:
31166947451fSStefano Zampini +  mat - the Mat object
31176947451fSStefano Zampini .  col - the column index
31186947451fSStefano Zampini -  v - the Vec object
31196947451fSStefano Zampini 
31206947451fSStefano Zampini    Level: intermediate
31216947451fSStefano Zampini 
31226947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
31236947451fSStefano Zampini @*/
31246947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec *v)
31256947451fSStefano Zampini {
31266947451fSStefano Zampini   PetscErrorCode ierr;
31276947451fSStefano Zampini 
31286947451fSStefano Zampini   PetscFunctionBegin;
31296947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
31306947451fSStefano Zampini   PetscValidType(A,1);
31316947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
31326947451fSStefano Zampini   PetscValidPointer(v,3);
31336947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
31346947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
31356947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
31366947451fSStefano Zampini   PetscFunctionReturn(0);
31376947451fSStefano Zampini }
31386947451fSStefano Zampini 
31396947451fSStefano Zampini /*@C
31406947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
31416947451fSStefano Zampini 
31426947451fSStefano Zampini    Collective
31436947451fSStefano Zampini 
31446947451fSStefano Zampini    Input Parameter:
31456947451fSStefano Zampini +  mat - the Mat object
31466947451fSStefano Zampini -  col - the column index
31476947451fSStefano Zampini 
31486947451fSStefano Zampini    Output Parameter:
31496947451fSStefano Zampini .  v - the vector
31506947451fSStefano Zampini 
31516947451fSStefano Zampini    Notes:
31526947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
31536947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
31546947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
31556947451fSStefano Zampini 
31566947451fSStefano Zampini    Level: intermediate
31576947451fSStefano Zampini 
31586947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
31596947451fSStefano Zampini @*/
31606947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec *v)
31616947451fSStefano Zampini {
31626947451fSStefano Zampini   PetscErrorCode ierr;
31636947451fSStefano Zampini 
31646947451fSStefano Zampini   PetscFunctionBegin;
31656947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
31666947451fSStefano Zampini   PetscValidType(A,1);
31676947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
31686947451fSStefano Zampini   PetscValidPointer(v,3);
31696947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
31706947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
31716947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
31726947451fSStefano Zampini   PetscFunctionReturn(0);
31736947451fSStefano Zampini }
31746947451fSStefano Zampini 
31756947451fSStefano Zampini /*@C
31766947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
31776947451fSStefano Zampini 
31786947451fSStefano Zampini    Collective
31796947451fSStefano Zampini 
31806947451fSStefano Zampini    Input Parameter:
31816947451fSStefano Zampini +  mat - the Mat object
31826947451fSStefano Zampini .  col - the column index
31836947451fSStefano Zampini -  v - the Vec object
31846947451fSStefano Zampini 
31856947451fSStefano Zampini    Level: intermediate
31866947451fSStefano Zampini 
31876947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecWrite()
31886947451fSStefano Zampini @*/
31896947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec *v)
31906947451fSStefano Zampini {
31916947451fSStefano Zampini   PetscErrorCode ierr;
31926947451fSStefano Zampini 
31936947451fSStefano Zampini   PetscFunctionBegin;
31946947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
31956947451fSStefano Zampini   PetscValidType(A,1);
31966947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
31976947451fSStefano Zampini   PetscValidPointer(v,3);
31986947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
31996947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
32006947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
32016947451fSStefano Zampini   PetscFunctionReturn(0);
32026947451fSStefano Zampini }
32036947451fSStefano Zampini 
32046947451fSStefano Zampini /*@C
32056947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
32066947451fSStefano Zampini 
32076947451fSStefano Zampini    Collective
32086947451fSStefano Zampini 
32096947451fSStefano Zampini    Input Parameter:
32106947451fSStefano Zampini +  mat - the Mat object
32116947451fSStefano Zampini -  col - the column index
32126947451fSStefano Zampini 
32136947451fSStefano Zampini    Output Parameter:
32146947451fSStefano Zampini .  v - the vector
32156947451fSStefano Zampini 
32166947451fSStefano Zampini    Notes:
32176947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
32186947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
32196947451fSStefano Zampini 
32206947451fSStefano Zampini    Level: intermediate
32216947451fSStefano Zampini 
32226947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
32236947451fSStefano Zampini @*/
32246947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec *v)
32256947451fSStefano Zampini {
32266947451fSStefano Zampini   PetscErrorCode ierr;
32276947451fSStefano Zampini 
32286947451fSStefano Zampini   PetscFunctionBegin;
32296947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
32306947451fSStefano Zampini   PetscValidType(A,1);
32316947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
32326947451fSStefano Zampini   PetscValidPointer(v,3);
32336947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
32346947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
32356947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
32366947451fSStefano Zampini   PetscFunctionReturn(0);
32376947451fSStefano Zampini }
32386947451fSStefano Zampini 
32396947451fSStefano Zampini /*@C
32406947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
32416947451fSStefano Zampini 
32426947451fSStefano Zampini    Collective
32436947451fSStefano Zampini 
32446947451fSStefano Zampini    Input Parameter:
32456947451fSStefano Zampini +  mat - the Mat object
32466947451fSStefano Zampini .  col - the column index
32476947451fSStefano Zampini -  v - the Vec object
32486947451fSStefano Zampini 
32496947451fSStefano Zampini    Level: intermediate
32506947451fSStefano Zampini 
32516947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead()
32526947451fSStefano Zampini @*/
32536947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec *v)
32546947451fSStefano Zampini {
32556947451fSStefano Zampini   PetscErrorCode ierr;
32566947451fSStefano Zampini 
32576947451fSStefano Zampini   PetscFunctionBegin;
32586947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
32596947451fSStefano Zampini   PetscValidType(A,1);
32606947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
32616947451fSStefano Zampini   PetscValidPointer(v,3);
32626947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
32636947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
32646947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
32656947451fSStefano Zampini   PetscFunctionReturn(0);
32666947451fSStefano Zampini }
3267