xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 6947451f174971b5cbba4c8ab49dd392302c23da)
1be1d678aSKris Buschelman 
267e560aaSBarry Smith /*
367e560aaSBarry Smith      Defines the basic matrix operations for sequential dense.
467e560aaSBarry Smith */
5289bc588SBarry Smith 
6dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/
7c6db04a5SJed Brown #include <petscblaslapack.h>
8289bc588SBarry Smith 
96a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h>
10b2573a8aSBarry Smith 
11ca15aa20SStefano Zampini PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian)
128c178816SStefano Zampini {
138c178816SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
148c178816SStefano Zampini   PetscInt       j, k, n = A->rmap->n;
15ca15aa20SStefano Zampini   PetscScalar    *v;
16ca15aa20SStefano Zampini   PetscErrorCode ierr;
178c178816SStefano Zampini 
188c178816SStefano Zampini   PetscFunctionBegin;
198c178816SStefano Zampini   if (A->rmap->n != A->cmap->n) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot symmetrize a rectangular matrix");
20ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
218c178816SStefano Zampini   if (!hermitian) {
228c178816SStefano Zampini     for (k=0;k<n;k++) {
238c178816SStefano Zampini       for (j=k;j<n;j++) {
24ca15aa20SStefano Zampini         v[j*mat->lda + k] = v[k*mat->lda + j];
258c178816SStefano Zampini       }
268c178816SStefano Zampini     }
278c178816SStefano Zampini   } else {
288c178816SStefano Zampini     for (k=0;k<n;k++) {
298c178816SStefano Zampini       for (j=k;j<n;j++) {
30ca15aa20SStefano Zampini         v[j*mat->lda + k] = PetscConj(v[k*mat->lda + j]);
318c178816SStefano Zampini       }
328c178816SStefano Zampini     }
338c178816SStefano Zampini   }
34ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
358c178816SStefano Zampini   PetscFunctionReturn(0);
368c178816SStefano Zampini }
378c178816SStefano Zampini 
3805709791SSatish Balay PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A)
398c178816SStefano Zampini {
408c178816SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
418c178816SStefano Zampini   PetscErrorCode ierr;
428c178816SStefano Zampini   PetscBLASInt   info,n;
438c178816SStefano Zampini 
448c178816SStefano Zampini   PetscFunctionBegin;
458c178816SStefano Zampini   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
468c178816SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
478c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
488c178816SStefano Zampini     if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
498c178816SStefano Zampini     if (!mat->fwork) {
508c178816SStefano Zampini       mat->lfwork = n;
518c178816SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
528c178816SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
538c178816SStefano Zampini     }
5400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
558c178816SStefano Zampini     PetscStackCallBLAS("LAPACKgetri",LAPACKgetri_(&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
5600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
57ca15aa20SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
588c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
598c178816SStefano Zampini     if (A->spd) {
6000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
618c178816SStefano Zampini       PetscStackCallBLAS("LAPACKpotri",LAPACKpotri_("L",&n,mat->v,&mat->lda,&info));
6200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
638c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
648c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
658c178816SStefano Zampini     } else if (A->hermitian) {
668c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
678c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
6800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
698c178816SStefano Zampini       PetscStackCallBLAS("LAPACKhetri",LAPACKhetri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
7000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
718c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
728c178816SStefano Zampini #endif
738c178816SStefano Zampini     } else { /* symmetric case */
748c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
758c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
7600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
778c178816SStefano Zampini       PetscStackCallBLAS("LAPACKsytri",LAPACKsytri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
7800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
798c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_FALSE);CHKERRQ(ierr);
808c178816SStefano Zampini     }
818c178816SStefano Zampini     if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad Inversion: zero pivot in row %D",(PetscInt)info-1);
82ca15aa20SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
838c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
848c178816SStefano Zampini 
858c178816SStefano Zampini   A->ops->solve             = NULL;
868c178816SStefano Zampini   A->ops->matsolve          = NULL;
878c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
888c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
898c178816SStefano Zampini   A->ops->solveadd          = NULL;
908c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
918c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
928c178816SStefano Zampini   ierr                      = PetscFree(A->solvertype);CHKERRQ(ierr);
938c178816SStefano Zampini   PetscFunctionReturn(0);
948c178816SStefano Zampini }
958c178816SStefano Zampini 
963f49a652SStefano Zampini PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
973f49a652SStefano Zampini {
983f49a652SStefano Zampini   PetscErrorCode    ierr;
993f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1003f49a652SStefano Zampini   PetscInt          m  = l->lda, n = A->cmap->n,r = A->rmap->n, i,j;
101ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
1023f49a652SStefano Zampini   const PetscScalar *xx;
1033f49a652SStefano Zampini 
1043f49a652SStefano Zampini   PetscFunctionBegin;
10576bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1063f49a652SStefano Zampini     for (i=0; i<N; i++) {
1073f49a652SStefano Zampini       if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1083f49a652SStefano Zampini       if (rows[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D requested to be zeroed greater than or equal number of rows %D",rows[i],A->rmap->n);
1093f49a652SStefano Zampini       if (rows[i] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Col %D requested to be zeroed greater than or equal number of cols %D",rows[i],A->cmap->n);
1103f49a652SStefano Zampini     }
11176bd3646SJed Brown   }
112ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1133f49a652SStefano Zampini 
1143f49a652SStefano Zampini   /* fix right hand side if needed */
1153f49a652SStefano Zampini   if (x && b) {
1166c4d906cSStefano Zampini     Vec xt;
1176c4d906cSStefano Zampini 
1186c4d906cSStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1196c4d906cSStefano Zampini     ierr = VecDuplicate(x,&xt);CHKERRQ(ierr);
1206c4d906cSStefano Zampini     ierr = VecCopy(x,xt);CHKERRQ(ierr);
1216c4d906cSStefano Zampini     ierr = VecScale(xt,-1.0);CHKERRQ(ierr);
1226c4d906cSStefano Zampini     ierr = MatMultAdd(A,xt,b,b);CHKERRQ(ierr);
1236c4d906cSStefano Zampini     ierr = VecDestroy(&xt);CHKERRQ(ierr);
1243f49a652SStefano Zampini     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1253f49a652SStefano Zampini     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
1263f49a652SStefano Zampini     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
1273f49a652SStefano Zampini     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1283f49a652SStefano Zampini     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
1293f49a652SStefano Zampini   }
1303f49a652SStefano Zampini 
131ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1323f49a652SStefano Zampini   for (i=0; i<N; i++) {
133ca15aa20SStefano Zampini     slot = v + rows[i]*m;
134580bdb30SBarry Smith     ierr = PetscArrayzero(slot,r);CHKERRQ(ierr);
1353f49a652SStefano Zampini   }
1363f49a652SStefano Zampini   for (i=0; i<N; i++) {
137ca15aa20SStefano Zampini     slot = v + rows[i];
1383f49a652SStefano Zampini     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
1393f49a652SStefano Zampini   }
1403f49a652SStefano Zampini   if (diag != 0.0) {
1413f49a652SStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1423f49a652SStefano Zampini     for (i=0; i<N; i++) {
143ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1443f49a652SStefano Zampini       *slot = diag;
1453f49a652SStefano Zampini     }
1463f49a652SStefano Zampini   }
147ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
1483f49a652SStefano Zampini   PetscFunctionReturn(0);
1493f49a652SStefano Zampini }
1503f49a652SStefano Zampini 
151abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C)
152abc3b08eSStefano Zampini {
153abc3b08eSStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)(C->data);
154abc3b08eSStefano Zampini   PetscErrorCode ierr;
155abc3b08eSStefano Zampini 
156abc3b08eSStefano Zampini   PetscFunctionBegin;
157ca15aa20SStefano Zampini   if (c->ptapwork) {
158ca15aa20SStefano Zampini     ierr = (*C->ops->matmultnumeric)(A,P,c->ptapwork);CHKERRQ(ierr);
159ca15aa20SStefano Zampini     ierr = (*C->ops->transposematmultnumeric)(P,c->ptapwork,C);CHKERRQ(ierr);
1604222ddf1SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"Must call MatPtAPSymbolic_SeqDense_SeqDense() first");
161abc3b08eSStefano Zampini   PetscFunctionReturn(0);
162abc3b08eSStefano Zampini }
163abc3b08eSStefano Zampini 
1644222ddf1SHong Zhang PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat C)
165abc3b08eSStefano Zampini {
166abc3b08eSStefano Zampini   Mat_SeqDense   *c;
167ca15aa20SStefano Zampini   PetscBool      flg;
168abc3b08eSStefano Zampini   PetscErrorCode ierr;
169abc3b08eSStefano Zampini 
170abc3b08eSStefano Zampini   PetscFunctionBegin;
171ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)P,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
1724222ddf1SHong Zhang   ierr = MatSetSizes(C,P->cmap->n,P->cmap->n,P->cmap->N,P->cmap->N);CHKERRQ(ierr);
1734222ddf1SHong Zhang   ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
1744222ddf1SHong Zhang   ierr = MatSeqDenseSetPreallocation(C,NULL);CHKERRQ(ierr);
1754222ddf1SHong Zhang   c    = (Mat_SeqDense*)C->data;
176ca15aa20SStefano Zampini   ierr = MatCreate(PetscObjectComm((PetscObject)A),&c->ptapwork);CHKERRQ(ierr);
177ca15aa20SStefano Zampini   ierr = MatSetSizes(c->ptapwork,A->rmap->n,P->cmap->n,A->rmap->N,P->cmap->N);CHKERRQ(ierr);
178ca15aa20SStefano Zampini   ierr = MatSetType(c->ptapwork,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
179ca15aa20SStefano Zampini   ierr = MatSeqDenseSetPreallocation(c->ptapwork,NULL);CHKERRQ(ierr);
180abc3b08eSStefano Zampini   PetscFunctionReturn(0);
181abc3b08eSStefano Zampini }
182abc3b08eSStefano Zampini 
183cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
184b49cda9fSStefano Zampini {
185a13144ffSStefano Zampini   Mat            B = NULL;
186b49cda9fSStefano Zampini   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
187b49cda9fSStefano Zampini   Mat_SeqDense   *b;
188b49cda9fSStefano Zampini   PetscErrorCode ierr;
189b49cda9fSStefano Zampini   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i;
190b49cda9fSStefano Zampini   MatScalar      *av=a->a;
191a13144ffSStefano Zampini   PetscBool      isseqdense;
192b49cda9fSStefano Zampini 
193b49cda9fSStefano Zampini   PetscFunctionBegin;
194a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
195a13144ffSStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense);CHKERRQ(ierr);
196a32993e3SJed Brown     if (!isseqdense) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type_name);
197a13144ffSStefano Zampini   }
198a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
199b49cda9fSStefano Zampini     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
200b49cda9fSStefano Zampini     ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
201b49cda9fSStefano Zampini     ierr = MatSetType(B,MATSEQDENSE);CHKERRQ(ierr);
202b49cda9fSStefano Zampini     ierr = MatSeqDenseSetPreallocation(B,NULL);CHKERRQ(ierr);
203b49cda9fSStefano Zampini     b    = (Mat_SeqDense*)(B->data);
204a13144ffSStefano Zampini   } else {
205a13144ffSStefano Zampini     b    = (Mat_SeqDense*)((*newmat)->data);
206580bdb30SBarry Smith     ierr = PetscArrayzero(b->v,m*n);CHKERRQ(ierr);
207a13144ffSStefano Zampini   }
208b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
209b49cda9fSStefano Zampini     PetscInt j;
210b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
211b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
212b49cda9fSStefano Zampini       aj++;
213b49cda9fSStefano Zampini       av++;
214b49cda9fSStefano Zampini     }
215b49cda9fSStefano Zampini     ai++;
216b49cda9fSStefano Zampini   }
217b49cda9fSStefano Zampini 
218511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
219a13144ffSStefano Zampini     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
220a13144ffSStefano Zampini     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22128be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
222b49cda9fSStefano Zampini   } else {
223a13144ffSStefano Zampini     if (B) *newmat = B;
224a13144ffSStefano Zampini     ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
225a13144ffSStefano Zampini     ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
226b49cda9fSStefano Zampini   }
227b49cda9fSStefano Zampini   PetscFunctionReturn(0);
228b49cda9fSStefano Zampini }
229b49cda9fSStefano Zampini 
230cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
2316a63e612SBarry Smith {
2326a63e612SBarry Smith   Mat            B;
2336a63e612SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2346a63e612SBarry Smith   PetscErrorCode ierr;
2359399e1b8SMatthew G. Knepley   PetscInt       i, j;
2369399e1b8SMatthew G. Knepley   PetscInt       *rows, *nnz;
2379399e1b8SMatthew G. Knepley   MatScalar      *aa = a->v, *vals;
2386a63e612SBarry Smith 
2396a63e612SBarry Smith   PetscFunctionBegin;
240ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
2416a63e612SBarry Smith   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
2426a63e612SBarry Smith   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
2439399e1b8SMatthew G. Knepley   ierr = PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals);CHKERRQ(ierr);
2449399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2459399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) ++nnz[i];
2466a63e612SBarry Smith     aa += a->lda;
2476a63e612SBarry Smith   }
2489399e1b8SMatthew G. Knepley   ierr = MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz);CHKERRQ(ierr);
2499399e1b8SMatthew G. Knepley   aa = a->v;
2509399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2519399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2529399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) {rows[numRows] = i; vals[numRows++] = aa[i];}
2539399e1b8SMatthew G. Knepley     ierr = MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr);
2549399e1b8SMatthew G. Knepley     aa  += a->lda;
2559399e1b8SMatthew G. Knepley   }
2569399e1b8SMatthew G. Knepley   ierr = PetscFree3(rows,nnz,vals);CHKERRQ(ierr);
2576a63e612SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2586a63e612SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2596a63e612SBarry Smith 
260511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
26128be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
2626a63e612SBarry Smith   } else {
2636a63e612SBarry Smith     *newmat = B;
2646a63e612SBarry Smith   }
2656a63e612SBarry Smith   PetscFunctionReturn(0);
2666a63e612SBarry Smith }
2676a63e612SBarry Smith 
268ca15aa20SStefano Zampini PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
2691987afe7SBarry Smith {
2701987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
271ca15aa20SStefano Zampini   const PetscScalar *xv;
272ca15aa20SStefano Zampini   PetscScalar       *yv;
2730805154bSBarry Smith   PetscBLASInt      N,m,ldax,lday,one = 1;
274efee365bSSatish Balay   PetscErrorCode    ierr;
2753a40ed3dSBarry Smith 
2763a40ed3dSBarry Smith   PetscFunctionBegin;
277ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(X,&xv);CHKERRQ(ierr);
278ca15aa20SStefano Zampini   ierr = MatDenseGetArray(Y,&yv);CHKERRQ(ierr);
279c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n*X->cmap->n,&N);CHKERRQ(ierr);
280c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n,&m);CHKERRQ(ierr);
281c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->lda,&ldax);CHKERRQ(ierr);
282c5df96a5SBarry Smith   ierr = PetscBLASIntCast(y->lda,&lday);CHKERRQ(ierr);
283a5ce6ee0Svictorle   if (ldax>m || lday>m) {
284ca15aa20SStefano Zampini     PetscInt j;
285ca15aa20SStefano Zampini 
286d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
287ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&alpha,xv+j*ldax,&one,yv+j*lday,&one));
288a5ce6ee0Svictorle     }
289a5ce6ee0Svictorle   } else {
290ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&alpha,xv,&one,yv,&one));
291a5ce6ee0Svictorle   }
292ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(X,&xv);CHKERRQ(ierr);
293ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(Y,&yv);CHKERRQ(ierr);
2940450473dSBarry Smith   ierr = PetscLogFlops(PetscMax(2*N-1,0));CHKERRQ(ierr);
2953a40ed3dSBarry Smith   PetscFunctionReturn(0);
2961987afe7SBarry Smith }
2971987afe7SBarry Smith 
298e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
299289bc588SBarry Smith {
300ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n*A->cmap->n;
3013a40ed3dSBarry Smith 
3023a40ed3dSBarry Smith   PetscFunctionBegin;
3034e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
304ca15aa20SStefano Zampini   info->nz_allocated      = N;
305ca15aa20SStefano Zampini   info->nz_used           = N;
306ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
307ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
3084e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3097adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3104e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3114e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3124e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3133a40ed3dSBarry Smith   PetscFunctionReturn(0);
314289bc588SBarry Smith }
315289bc588SBarry Smith 
316637a0070SStefano Zampini PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
31780cd9d93SLois Curfman McInnes {
318273d9f13SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
319ca15aa20SStefano Zampini   PetscScalar    *v;
320efee365bSSatish Balay   PetscErrorCode ierr;
321c5df96a5SBarry Smith   PetscBLASInt   one = 1,j,nz,lda;
32280cd9d93SLois Curfman McInnes 
3233a40ed3dSBarry Smith   PetscFunctionBegin;
324ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
325c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->lda,&lda);CHKERRQ(ierr);
326d0f46423SBarry Smith   if (lda>A->rmap->n) {
327c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n,&nz);CHKERRQ(ierr);
328d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
329ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v+j*lda,&one));
330a5ce6ee0Svictorle     }
331a5ce6ee0Svictorle   } else {
332c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz);CHKERRQ(ierr);
333ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v,&one));
334a5ce6ee0Svictorle   }
335efee365bSSatish Balay   ierr = PetscLogFlops(nz);CHKERRQ(ierr);
336ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
3373a40ed3dSBarry Smith   PetscFunctionReturn(0);
33880cd9d93SLois Curfman McInnes }
33980cd9d93SLois Curfman McInnes 
340e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3411cbb95d3SBarry Smith {
3421cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
343ca15aa20SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
344ca15aa20SStefano Zampini   const PetscScalar *v;
345ca15aa20SStefano Zampini   PetscErrorCode    ierr;
3461cbb95d3SBarry Smith 
3471cbb95d3SBarry Smith   PetscFunctionBegin;
3481cbb95d3SBarry Smith   *fl = PETSC_FALSE;
349d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
350ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
3511cbb95d3SBarry Smith   for (i=0; i<m; i++) {
352ca15aa20SStefano Zampini     for (j=i; j<m; j++) {
353637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) {
354637a0070SStefano Zampini         goto restore;
3551cbb95d3SBarry Smith       }
3561cbb95d3SBarry Smith     }
357637a0070SStefano Zampini   }
3581cbb95d3SBarry Smith   *fl  = PETSC_TRUE;
359637a0070SStefano Zampini restore:
360637a0070SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
361637a0070SStefano Zampini   PetscFunctionReturn(0);
362637a0070SStefano Zampini }
363637a0070SStefano Zampini 
364637a0070SStefano Zampini static PetscErrorCode MatIsSymmetric_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
365637a0070SStefano Zampini {
366637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
367637a0070SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
368637a0070SStefano Zampini   const PetscScalar *v;
369637a0070SStefano Zampini   PetscErrorCode    ierr;
370637a0070SStefano Zampini 
371637a0070SStefano Zampini   PetscFunctionBegin;
372637a0070SStefano Zampini   *fl = PETSC_FALSE;
373637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
374637a0070SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
375637a0070SStefano Zampini   for (i=0; i<m; i++) {
376637a0070SStefano Zampini     for (j=i; j<m; j++) {
377637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - v[j+i*N]) > rtol) {
378637a0070SStefano Zampini         goto restore;
379637a0070SStefano Zampini       }
380637a0070SStefano Zampini     }
381637a0070SStefano Zampini   }
382637a0070SStefano Zampini   *fl  = PETSC_TRUE;
383637a0070SStefano Zampini restore:
384637a0070SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
3851cbb95d3SBarry Smith   PetscFunctionReturn(0);
3861cbb95d3SBarry Smith }
3871cbb95d3SBarry Smith 
388ca15aa20SStefano Zampini PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
389b24902e0SBarry Smith {
390ca15aa20SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
391b24902e0SBarry Smith   PetscErrorCode ierr;
392b24902e0SBarry Smith   PetscInt       lda = (PetscInt)mat->lda,j,m;
393b24902e0SBarry Smith 
394b24902e0SBarry Smith   PetscFunctionBegin;
395aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr);
396aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr);
3970298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr);
398b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
399ca15aa20SStefano Zampini     const PetscScalar *av;
400ca15aa20SStefano Zampini     PetscScalar       *v;
401ca15aa20SStefano Zampini 
402ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
403ca15aa20SStefano Zampini     ierr = MatDenseGetArray(newi,&v);CHKERRQ(ierr);
404d0f46423SBarry Smith     if (lda>A->rmap->n) {
405d0f46423SBarry Smith       m = A->rmap->n;
406d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
407ca15aa20SStefano Zampini         ierr = PetscArraycpy(v+j*m,av+j*lda,m);CHKERRQ(ierr);
408b24902e0SBarry Smith       }
409b24902e0SBarry Smith     } else {
410ca15aa20SStefano Zampini       ierr = PetscArraycpy(v,av,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
411b24902e0SBarry Smith     }
412ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(newi,&v);CHKERRQ(ierr);
413ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
414b24902e0SBarry Smith   }
415b24902e0SBarry Smith   PetscFunctionReturn(0);
416b24902e0SBarry Smith }
417b24902e0SBarry Smith 
418ca15aa20SStefano Zampini PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
41902cad45dSBarry Smith {
4206849ba73SBarry Smith   PetscErrorCode ierr;
42102cad45dSBarry Smith 
4223a40ed3dSBarry Smith   PetscFunctionBegin;
423ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr);
424d0f46423SBarry Smith   ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4255c9eb25fSBarry Smith   ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
426719d5645SBarry Smith   ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr);
427b24902e0SBarry Smith   PetscFunctionReturn(0);
428b24902e0SBarry Smith }
429b24902e0SBarry Smith 
430e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
431289bc588SBarry Smith {
4324482741eSBarry Smith   MatFactorInfo  info;
433a093e273SMatthew Knepley   PetscErrorCode ierr;
4343a40ed3dSBarry Smith 
4353a40ed3dSBarry Smith   PetscFunctionBegin;
436c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
437ca15aa20SStefano Zampini   ierr = (*fact->ops->lufactor)(fact,0,0,&info);CHKERRQ(ierr);
4383a40ed3dSBarry Smith   PetscFunctionReturn(0);
439289bc588SBarry Smith }
4406ee01492SSatish Balay 
441e0877f53SBarry Smith static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy)
442289bc588SBarry Smith {
443c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
4446849ba73SBarry Smith   PetscErrorCode    ierr;
445f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
446f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
447c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
44867e560aaSBarry Smith 
4493a40ed3dSBarry Smith   PetscFunctionBegin;
450c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
451f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4521ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
453580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
454d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_LU) {
45500121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4568b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
45700121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
458e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
459d5f3da31SBarry Smith   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
460a49dc2a2SStefano Zampini     if (A->spd) {
46100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4628b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
46300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
464e32f2f54SBarry Smith       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
465a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
466a49dc2a2SStefano Zampini     } else if (A->hermitian) {
46700121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
468a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
46900121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
470a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
471a49dc2a2SStefano Zampini #endif
472a49dc2a2SStefano Zampini     } else { /* symmetric case */
47300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
474a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
47500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
476a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
477a49dc2a2SStefano Zampini     }
4782205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
479f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4801ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
481dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
4823a40ed3dSBarry Smith   PetscFunctionReturn(0);
483289bc588SBarry Smith }
4846ee01492SSatish Balay 
485e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X)
48685e2c93fSHong Zhang {
48785e2c93fSHong Zhang   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
48885e2c93fSHong Zhang   PetscErrorCode    ierr;
4891683a169SBarry Smith   const PetscScalar *b;
4901683a169SBarry Smith   PetscScalar       *x;
491efb80c78SLisandro Dalcin   PetscInt          n;
492783b601eSJed Brown   PetscBLASInt      nrhs,info,m;
49385e2c93fSHong Zhang 
49485e2c93fSHong Zhang   PetscFunctionBegin;
495c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
4960298fd71SBarry Smith   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
497c5df96a5SBarry Smith   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
4981683a169SBarry Smith   ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
4998c778c55SBarry Smith   ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr);
50085e2c93fSHong Zhang 
501580bdb30SBarry Smith   ierr = PetscArraycpy(x,b,m*nrhs);CHKERRQ(ierr);
50285e2c93fSHong Zhang 
50385e2c93fSHong Zhang   if (A->factortype == MAT_FACTOR_LU) {
50400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5058b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
50600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
50785e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
50885e2c93fSHong Zhang   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
509a49dc2a2SStefano Zampini     if (A->spd) {
51000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5118b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
51200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
51385e2c93fSHong Zhang       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
514a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
515a49dc2a2SStefano Zampini     } else if (A->hermitian) {
51600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
517a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
51800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
519a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
520a49dc2a2SStefano Zampini #endif
521a49dc2a2SStefano Zampini     } else { /* symmetric case */
52200121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
523a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
52400121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
525a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
526a49dc2a2SStefano Zampini     }
5272205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
52885e2c93fSHong Zhang 
5291683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
5308c778c55SBarry Smith   ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr);
53185e2c93fSHong Zhang   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
53285e2c93fSHong Zhang   PetscFunctionReturn(0);
53385e2c93fSHong Zhang }
53485e2c93fSHong Zhang 
53500121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
53600121966SStefano Zampini 
537e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
538da3a660dSBarry Smith {
539c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
540dfbe8321SBarry Smith   PetscErrorCode    ierr;
541f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
542f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
543c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
54467e560aaSBarry Smith 
5453a40ed3dSBarry Smith   PetscFunctionBegin;
546c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
547f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5481ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
549580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
5508208b9aeSStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
55100121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5528b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
55300121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
554e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve");
5558208b9aeSStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
556a49dc2a2SStefano Zampini     if (A->spd) {
55700121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
55800121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
55900121966SStefano Zampini #endif
56000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5618b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
56200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
56300121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
56400121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
56500121966SStefano Zampini #endif
566a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
567a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
568a49dc2a2SStefano Zampini     } else if (A->hermitian) {
56900121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
57000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
57100121966SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
57200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
57300121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
574ae7cfcebSSatish Balay #endif
575a49dc2a2SStefano Zampini     } else { /* symmetric case */
57600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
577a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
57800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
579a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
580da3a660dSBarry Smith     }
581a49dc2a2SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
582f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5831ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
584dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
5853a40ed3dSBarry Smith   PetscFunctionReturn(0);
586da3a660dSBarry Smith }
5876ee01492SSatish Balay 
588db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
589db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
590db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
591ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
592db4efbfdSBarry Smith {
593db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
594db4efbfdSBarry Smith   PetscErrorCode ierr;
595db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
596db4efbfdSBarry Smith 
597db4efbfdSBarry Smith   PetscFunctionBegin;
598c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
599c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
600db4efbfdSBarry Smith   if (!mat->pivots) {
6018208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
6023bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
603db4efbfdSBarry Smith   }
604db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
6058e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6068b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
6078e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
6088e57ea43SSatish Balay 
609e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
610e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
6118208b9aeSStefano Zampini 
612db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6138208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
614db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
615d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
616db4efbfdSBarry Smith 
617f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
618f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
619f6224b95SHong Zhang 
620dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
621db4efbfdSBarry Smith   PetscFunctionReturn(0);
622db4efbfdSBarry Smith }
623db4efbfdSBarry Smith 
624a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
625ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
626db4efbfdSBarry Smith {
627db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
628db4efbfdSBarry Smith   PetscErrorCode ierr;
629c5df96a5SBarry Smith   PetscBLASInt   info,n;
630db4efbfdSBarry Smith 
631db4efbfdSBarry Smith   PetscFunctionBegin;
632c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
633db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
634a49dc2a2SStefano Zampini   if (A->spd) {
63500121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6368b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
63700121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
638a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
639a49dc2a2SStefano Zampini   } else if (A->hermitian) {
640a49dc2a2SStefano Zampini     if (!mat->pivots) {
641a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
642a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
643a49dc2a2SStefano Zampini     }
644a49dc2a2SStefano Zampini     if (!mat->fwork) {
645a49dc2a2SStefano Zampini       PetscScalar dummy;
646a49dc2a2SStefano Zampini 
647a49dc2a2SStefano Zampini       mat->lfwork = -1;
64800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
649a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
65000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
651a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
652a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
653a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
654a49dc2a2SStefano Zampini     }
65500121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
656a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
65700121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
658a49dc2a2SStefano Zampini #endif
659a49dc2a2SStefano Zampini   } else { /* symmetric case */
660a49dc2a2SStefano Zampini     if (!mat->pivots) {
661a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
662a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
663a49dc2a2SStefano Zampini     }
664a49dc2a2SStefano Zampini     if (!mat->fwork) {
665a49dc2a2SStefano Zampini       PetscScalar dummy;
666a49dc2a2SStefano Zampini 
667a49dc2a2SStefano Zampini       mat->lfwork = -1;
66800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
669a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
67000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
671a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
672a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
673a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
674a49dc2a2SStefano Zampini     }
67500121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
676a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
67700121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
678a49dc2a2SStefano Zampini   }
679e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
6808208b9aeSStefano Zampini 
681db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6828208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
683db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
684d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
6852205254eSKarl Rupp 
686f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
687f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
688f6224b95SHong Zhang 
689eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
690db4efbfdSBarry Smith   PetscFunctionReturn(0);
691db4efbfdSBarry Smith }
692db4efbfdSBarry Smith 
693db4efbfdSBarry Smith 
6940481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
695db4efbfdSBarry Smith {
696db4efbfdSBarry Smith   PetscErrorCode ierr;
697db4efbfdSBarry Smith   MatFactorInfo  info;
698db4efbfdSBarry Smith 
699db4efbfdSBarry Smith   PetscFunctionBegin;
700db4efbfdSBarry Smith   info.fill = 1.0;
7012205254eSKarl Rupp 
702c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
703ca15aa20SStefano Zampini   ierr = (*fact->ops->choleskyfactor)(fact,0,&info);CHKERRQ(ierr);
704db4efbfdSBarry Smith   PetscFunctionReturn(0);
705db4efbfdSBarry Smith }
706db4efbfdSBarry Smith 
707ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
708db4efbfdSBarry Smith {
709db4efbfdSBarry Smith   PetscFunctionBegin;
710c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
7111bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
712719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
713bd443b22SStefano Zampini   fact->ops->solve                 = MatSolve_SeqDense;
714bd443b22SStefano Zampini   fact->ops->matsolve              = MatMatSolve_SeqDense;
715bd443b22SStefano Zampini   fact->ops->solvetranspose        = MatSolveTranspose_SeqDense;
716db4efbfdSBarry Smith   PetscFunctionReturn(0);
717db4efbfdSBarry Smith }
718db4efbfdSBarry Smith 
719ca15aa20SStefano Zampini PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
720db4efbfdSBarry Smith {
721db4efbfdSBarry Smith   PetscFunctionBegin;
722b66fe19dSMatthew G Knepley   fact->preallocated           = PETSC_TRUE;
723c3ef05f6SHong Zhang   fact->assembled              = PETSC_TRUE;
724719d5645SBarry Smith   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
725bd443b22SStefano Zampini   fact->ops->solve             = MatSolve_SeqDense;
726bd443b22SStefano Zampini   fact->ops->matsolve          = MatMatSolve_SeqDense;
727bd443b22SStefano Zampini   fact->ops->solvetranspose    = MatSolveTranspose_SeqDense;
728db4efbfdSBarry Smith   PetscFunctionReturn(0);
729db4efbfdSBarry Smith }
730db4efbfdSBarry Smith 
731ca15aa20SStefano Zampini /* uses LAPACK */
732cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
733db4efbfdSBarry Smith {
734db4efbfdSBarry Smith   PetscErrorCode ierr;
735db4efbfdSBarry Smith 
736db4efbfdSBarry Smith   PetscFunctionBegin;
737ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
738db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
739ca15aa20SStefano Zampini   ierr = MatSetType(*fact,MATDENSE);CHKERRQ(ierr);
740db4efbfdSBarry Smith   if (ftype == MAT_FACTOR_LU) {
741db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
742db4efbfdSBarry Smith   } else {
743db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
744db4efbfdSBarry Smith   }
745d5f3da31SBarry Smith   (*fact)->factortype = ftype;
74600c67f3bSHong Zhang 
74700c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
74800c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
749db4efbfdSBarry Smith   PetscFunctionReturn(0);
750db4efbfdSBarry Smith }
751db4efbfdSBarry Smith 
752289bc588SBarry Smith /* ------------------------------------------------------------------*/
753e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
754289bc588SBarry Smith {
755c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
756d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
757d9ca1df4SBarry Smith   const PetscScalar *b;
758dfbe8321SBarry Smith   PetscErrorCode    ierr;
759d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
760c5df96a5SBarry Smith   PetscBLASInt      o = 1,bm;
761289bc588SBarry Smith 
7623a40ed3dSBarry Smith   PetscFunctionBegin;
763ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
764c70f7ee4SJunchao Zhang   if (A->offloadmask == PETSC_OFFLOAD_GPU) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
765ca15aa20SStefano Zampini #endif
766422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
767c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
768289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
7693bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
7702dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
771289bc588SBarry Smith   }
7721ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
773d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
774b965ef7fSBarry Smith   its  = its*lits;
775e32f2f54SBarry Smith   if (its <= 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits);
776289bc588SBarry Smith   while (its--) {
777fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
778289bc588SBarry Smith       for (i=0; i<m; i++) {
7793bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
78055a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
781289bc588SBarry Smith       }
782289bc588SBarry Smith     }
783fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
784289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
7853bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
78655a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
787289bc588SBarry Smith       }
788289bc588SBarry Smith     }
789289bc588SBarry Smith   }
790d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
7911ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
7923a40ed3dSBarry Smith   PetscFunctionReturn(0);
793289bc588SBarry Smith }
794289bc588SBarry Smith 
795289bc588SBarry Smith /* -----------------------------------------------------------------*/
796ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
797289bc588SBarry Smith {
798c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
799d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
800d9ca1df4SBarry Smith   PetscScalar       *y;
801dfbe8321SBarry Smith   PetscErrorCode    ierr;
8020805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
803ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
8043a40ed3dSBarry Smith 
8053a40ed3dSBarry Smith   PetscFunctionBegin;
806c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
807c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
808d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8092bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
8105ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8115ac36cfcSBarry Smith     PetscBLASInt i;
8125ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
8135ac36cfcSBarry Smith   } else {
8148b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
8155ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
8165ac36cfcSBarry Smith   }
817d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8182bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
8193a40ed3dSBarry Smith   PetscFunctionReturn(0);
820289bc588SBarry Smith }
821800995b7SMatthew Knepley 
822ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
823289bc588SBarry Smith {
824c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
825d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
826dfbe8321SBarry Smith   PetscErrorCode    ierr;
8270805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
828d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
8293a40ed3dSBarry Smith 
8303a40ed3dSBarry Smith   PetscFunctionBegin;
831c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
832c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
833d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8342bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
8355ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8365ac36cfcSBarry Smith     PetscBLASInt i;
8375ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
8385ac36cfcSBarry Smith   } else {
8398b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
8405ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
8415ac36cfcSBarry Smith   }
842d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8432bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
8443a40ed3dSBarry Smith   PetscFunctionReturn(0);
845289bc588SBarry Smith }
8466ee01492SSatish Balay 
847ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
848289bc588SBarry Smith {
849c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
850d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
851d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
852dfbe8321SBarry Smith   PetscErrorCode    ierr;
8530805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
8543a40ed3dSBarry Smith 
8553a40ed3dSBarry Smith   PetscFunctionBegin;
856c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
857c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
858d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
859600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
860d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8611ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8628b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
863d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8641ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
865dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8663a40ed3dSBarry Smith   PetscFunctionReturn(0);
867289bc588SBarry Smith }
8686ee01492SSatish Balay 
869ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
870289bc588SBarry Smith {
871c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
872d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
873d9ca1df4SBarry Smith   PetscScalar       *y;
874dfbe8321SBarry Smith   PetscErrorCode    ierr;
8750805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
87687828ca2SBarry Smith   PetscScalar       _DOne=1.0;
8773a40ed3dSBarry Smith 
8783a40ed3dSBarry Smith   PetscFunctionBegin;
879c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
880c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
881d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
882600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
883d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8841ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8858b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
886d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8871ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
888dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8893a40ed3dSBarry Smith   PetscFunctionReturn(0);
890289bc588SBarry Smith }
891289bc588SBarry Smith 
892289bc588SBarry Smith /* -----------------------------------------------------------------*/
893e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
894289bc588SBarry Smith {
895c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
8966849ba73SBarry Smith   PetscErrorCode ierr;
89713f74950SBarry Smith   PetscInt       i;
89867e560aaSBarry Smith 
8993a40ed3dSBarry Smith   PetscFunctionBegin;
900d0f46423SBarry Smith   *ncols = A->cmap->n;
901289bc588SBarry Smith   if (cols) {
902854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
903d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
904289bc588SBarry Smith   }
905289bc588SBarry Smith   if (vals) {
906ca15aa20SStefano Zampini     const PetscScalar *v;
907ca15aa20SStefano Zampini 
908ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
909854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
910ca15aa20SStefano Zampini     v   += row;
911d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
912ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
913289bc588SBarry Smith   }
9143a40ed3dSBarry Smith   PetscFunctionReturn(0);
915289bc588SBarry Smith }
9166ee01492SSatish Balay 
917e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
918289bc588SBarry Smith {
919dfbe8321SBarry Smith   PetscErrorCode ierr;
9206e111a19SKarl Rupp 
921606d414cSSatish Balay   PetscFunctionBegin;
922606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
923606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
9243a40ed3dSBarry Smith   PetscFunctionReturn(0);
925289bc588SBarry Smith }
926289bc588SBarry Smith /* ----------------------------------------------------------------*/
927e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
928289bc588SBarry Smith {
929c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
930ca15aa20SStefano Zampini   PetscScalar      *av;
93113f74950SBarry Smith   PetscInt         i,j,idx=0;
932ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
933c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
934ca15aa20SStefano Zampini #endif
935ca15aa20SStefano Zampini   PetscErrorCode   ierr;
936d6dfbf8fSBarry Smith 
9373a40ed3dSBarry Smith   PetscFunctionBegin;
938ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&av);CHKERRQ(ierr);
939289bc588SBarry Smith   if (!mat->roworiented) {
940dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
941289bc588SBarry Smith       for (j=0; j<n; j++) {
942cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
943cf9c20a2SJed Brown         if (PetscUnlikelyDebug(indexn[j] >= A->cmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
944289bc588SBarry Smith         for (i=0; i<m; i++) {
945cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
946cf9c20a2SJed Brown           if (PetscUnlikelyDebug(indexm[i] >= A->rmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
947ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
948289bc588SBarry Smith         }
949289bc588SBarry Smith       }
9503a40ed3dSBarry Smith     } else {
951289bc588SBarry Smith       for (j=0; j<n; j++) {
952cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
953cf9c20a2SJed Brown         if (PetscUnlikelyDebug(indexn[j] >= A->cmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
954289bc588SBarry Smith         for (i=0; i<m; i++) {
955cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
956cf9c20a2SJed Brown           if (PetscUnlikelyDebug(indexm[i] >= A->rmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
957ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
958289bc588SBarry Smith         }
959289bc588SBarry Smith       }
960289bc588SBarry Smith     }
9613a40ed3dSBarry Smith   } else {
962dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
963e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
964cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
965cf9c20a2SJed Brown         if (PetscUnlikelyDebug(indexm[i] >= A->rmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
966e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
967cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
968cf9c20a2SJed Brown           if (PetscUnlikelyDebug(indexn[j] >= A->cmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
969ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
970e8d4e0b9SBarry Smith         }
971e8d4e0b9SBarry Smith       }
9723a40ed3dSBarry Smith     } else {
973289bc588SBarry Smith       for (i=0; i<m; i++) {
974cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
975cf9c20a2SJed Brown         if (PetscUnlikelyDebug(indexm[i] >= A->rmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
976289bc588SBarry Smith         for (j=0; j<n; j++) {
977cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
978cf9c20a2SJed Brown           if (PetscUnlikelyDebug(indexn[j] >= A->cmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
979ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
980289bc588SBarry Smith         }
981289bc588SBarry Smith       }
982289bc588SBarry Smith     }
983e8d4e0b9SBarry Smith   }
984ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
985ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
986c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
987c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
988ca15aa20SStefano Zampini #endif
989ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&av);CHKERRQ(ierr);
990ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
991c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
992ca15aa20SStefano Zampini #endif
9933a40ed3dSBarry Smith   PetscFunctionReturn(0);
994289bc588SBarry Smith }
995e8d4e0b9SBarry Smith 
996e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
997ae80bb75SLois Curfman McInnes {
998ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
999ca15aa20SStefano Zampini   const PetscScalar *vv;
100013f74950SBarry Smith   PetscInt          i,j;
1001ca15aa20SStefano Zampini   PetscErrorCode    ierr;
1002ae80bb75SLois Curfman McInnes 
10033a40ed3dSBarry Smith   PetscFunctionBegin;
1004ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1005ae80bb75SLois Curfman McInnes   /* row-oriented output */
1006ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
100797e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1008e32f2f54SBarry Smith     if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D requested larger than number rows %D",indexm[i],A->rmap->n);
1009ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
10106f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1011e32f2f54SBarry Smith       if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column %D requested larger than number columns %D",indexn[j],A->cmap->n);
1012ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1013ae80bb75SLois Curfman McInnes     }
1014ae80bb75SLois Curfman McInnes   }
1015ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
10163a40ed3dSBarry Smith   PetscFunctionReturn(0);
1017ae80bb75SLois Curfman McInnes }
1018ae80bb75SLois Curfman McInnes 
1019289bc588SBarry Smith /* -----------------------------------------------------------------*/
1020289bc588SBarry Smith 
10218491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1022aabbc4fbSShri Abhyankar {
1023aabbc4fbSShri Abhyankar   PetscErrorCode    ierr;
10248491ab44SLisandro Dalcin   PetscBool         skipHeader;
10258491ab44SLisandro Dalcin   PetscViewerFormat format;
10268491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
10278491ab44SLisandro Dalcin   const PetscScalar *v;
10288491ab44SLisandro Dalcin   PetscScalar       *vwork;
1029aabbc4fbSShri Abhyankar 
1030aabbc4fbSShri Abhyankar   PetscFunctionBegin;
10318491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
10328491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
10338491ab44SLisandro Dalcin   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
10348491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1035aabbc4fbSShri Abhyankar 
10368491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
10378491ab44SLisandro Dalcin 
10388491ab44SLisandro Dalcin   /* write matrix header */
10398491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
10408491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
10418491ab44SLisandro Dalcin   if (!skipHeader) {ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);}
10428491ab44SLisandro Dalcin 
10438491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
10448491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
10458491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
10468491ab44SLisandro Dalcin     /* store row lengths for each row */
10478491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
10488491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
10498491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
10508491ab44SLisandro Dalcin     /* store column indices (zero start index) */
10518491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
10528491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
10538491ab44SLisandro Dalcin         iwork[k] = j;
10548491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
10558491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
10568491ab44SLisandro Dalcin   }
10578491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
10588491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
10598491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
10608491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
10618491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
10628491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
10638491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
10648491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
10658491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
10668491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
10678491ab44SLisandro Dalcin   PetscFunctionReturn(0);
10688491ab44SLisandro Dalcin }
10698491ab44SLisandro Dalcin 
10708491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
10718491ab44SLisandro Dalcin {
10728491ab44SLisandro Dalcin   PetscErrorCode ierr;
10738491ab44SLisandro Dalcin   PetscBool      skipHeader;
10748491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
10758491ab44SLisandro Dalcin   PetscInt       rows,cols;
10768491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
10778491ab44SLisandro Dalcin 
10788491ab44SLisandro Dalcin   PetscFunctionBegin;
10798491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
10808491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
10818491ab44SLisandro Dalcin 
10828491ab44SLisandro Dalcin   if (!skipHeader) {
10838491ab44SLisandro Dalcin     ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
10848491ab44SLisandro Dalcin     if (header[0] != MAT_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
10858491ab44SLisandro Dalcin     M = header[1]; N = header[2];
10868491ab44SLisandro Dalcin     if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M);
10878491ab44SLisandro Dalcin     if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N);
10888491ab44SLisandro Dalcin     nz = header[3];
10898491ab44SLisandro Dalcin     if (nz != MATRIX_BINARY_FORMAT_DENSE && nz < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %D in file",nz);
1090aabbc4fbSShri Abhyankar   } else {
10918491ab44SLisandro Dalcin     ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
10928491ab44SLisandro Dalcin     if (M < 0 || N < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Matrix binary file header was skipped, thus the user must specify the global sizes of input matrix");
10938491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1094e6324fbbSBarry Smith   }
1095aabbc4fbSShri Abhyankar 
10968491ab44SLisandro Dalcin   /* setup global sizes if not set */
10978491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
10988491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
10998491ab44SLisandro Dalcin   ierr = MatSetUp(mat);CHKERRQ(ierr);
11008491ab44SLisandro Dalcin   /* check if global sizes are correct */
11018491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
11028491ab44SLisandro Dalcin   if (M != rows || N != cols) SETERRQ4(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different sizes (%d, %d) than the input matrix (%d, %d)",M,N,rows,cols);
1103aabbc4fbSShri Abhyankar 
11048491ab44SLisandro Dalcin   ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
11058491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
11068491ab44SLisandro Dalcin   ierr = MatDenseGetArray(mat,&v);CHKERRQ(ierr);
11078491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
11088491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
11098491ab44SLisandro Dalcin     PetscInt nnz = m*N;
11108491ab44SLisandro Dalcin     /* read in matrix values */
11118491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&vwork);CHKERRQ(ierr);
11128491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
11138491ab44SLisandro Dalcin     /* store values in column major order */
11148491ab44SLisandro Dalcin     for (j=0; j<N; j++)
11158491ab44SLisandro Dalcin       for (i=0; i<m; i++)
11168491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
11178491ab44SLisandro Dalcin     ierr = PetscFree(vwork);CHKERRQ(ierr);
11188491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
11198491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
11208491ab44SLisandro Dalcin     /* read in row lengths */
11218491ab44SLisandro Dalcin     ierr = PetscMalloc1(m,&rlens);CHKERRQ(ierr);
11228491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
11238491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
11248491ab44SLisandro Dalcin     /* read in column indices and values */
11258491ab44SLisandro Dalcin     ierr = PetscMalloc2(nnz,&icols,nnz,&vwork);CHKERRQ(ierr);
11268491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
11278491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
11288491ab44SLisandro Dalcin     /* store values in column major order */
11298491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
11308491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
11318491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
11328491ab44SLisandro Dalcin     ierr = PetscFree(rlens);CHKERRQ(ierr);
11338491ab44SLisandro Dalcin     ierr = PetscFree2(icols,vwork);CHKERRQ(ierr);
1134aabbc4fbSShri Abhyankar   }
11358491ab44SLisandro Dalcin   ierr = MatDenseRestoreArray(mat,&v);CHKERRQ(ierr);
11368491ab44SLisandro Dalcin   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
11378491ab44SLisandro Dalcin   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1138aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1139aabbc4fbSShri Abhyankar }
1140aabbc4fbSShri Abhyankar 
1141eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1142eb91f321SVaclav Hapla {
1143eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1144eb91f321SVaclav Hapla   PetscErrorCode ierr;
1145eb91f321SVaclav Hapla 
1146eb91f321SVaclav Hapla   PetscFunctionBegin;
1147eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1148eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1149eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
1150eb91f321SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1151eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1152eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1153eb91f321SVaclav Hapla   if (isbinary) {
11548491ab44SLisandro Dalcin     ierr = MatLoad_Dense_Binary(newMat,viewer);CHKERRQ(ierr);
1155eb91f321SVaclav Hapla   } else if (ishdf5) {
1156eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
1157eb91f321SVaclav Hapla     ierr = MatLoad_Dense_HDF5(newMat,viewer);CHKERRQ(ierr);
1158eb91f321SVaclav Hapla #else
1159eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1160eb91f321SVaclav Hapla #endif
1161eb91f321SVaclav Hapla   } else {
1162eb91f321SVaclav Hapla     SETERRQ2(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"Viewer type %s not yet supported for reading %s matrices",((PetscObject)viewer)->type_name,((PetscObject)newMat)->type_name);
1163eb91f321SVaclav Hapla   }
1164eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1165eb91f321SVaclav Hapla }
1166eb91f321SVaclav Hapla 
11676849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1168289bc588SBarry Smith {
1169932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1170dfbe8321SBarry Smith   PetscErrorCode    ierr;
117113f74950SBarry Smith   PetscInt          i,j;
11722dcb1b2aSMatthew Knepley   const char        *name;
1173ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1174f3ef73ceSBarry Smith   PetscViewerFormat format;
11755f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1176ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
11775f481a85SSatish Balay #endif
1178932b0c3eSLois Curfman McInnes 
11793a40ed3dSBarry Smith   PetscFunctionBegin;
1180ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1181b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1182456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
11833a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1184fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1185d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1186d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1187ca15aa20SStefano Zampini       v    = av + i;
118877431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1189d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1190aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1191329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
119257622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1193329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
119457622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
11956831982aSBarry Smith         }
119680cd9d93SLois Curfman McInnes #else
11976831982aSBarry Smith         if (*v) {
119857622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
11996831982aSBarry Smith         }
120080cd9d93SLois Curfman McInnes #endif
12011b807ce4Svictorle         v += a->lda;
120280cd9d93SLois Curfman McInnes       }
1203b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
120480cd9d93SLois Curfman McInnes     }
1205d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
12063a40ed3dSBarry Smith   } else {
1207d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1208aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
120947989497SBarry Smith     /* determine if matrix has all real values */
1210ca15aa20SStefano Zampini     v = av;
1211d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1212ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
121347989497SBarry Smith     }
121447989497SBarry Smith #endif
1215fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
12163a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1217d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1218d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1219fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1220ffac6cdbSBarry Smith     }
1221ffac6cdbSBarry Smith 
1222d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1223ca15aa20SStefano Zampini       v = av + i;
1224d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1225aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
122647989497SBarry Smith         if (allreal) {
1227c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
122847989497SBarry Smith         } else {
1229c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
123047989497SBarry Smith         }
1231289bc588SBarry Smith #else
1232c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1233289bc588SBarry Smith #endif
12341b807ce4Svictorle         v += a->lda;
1235289bc588SBarry Smith       }
1236b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1237289bc588SBarry Smith     }
1238fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1239b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1240ffac6cdbSBarry Smith     }
1241d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1242da3a660dSBarry Smith   }
1243ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1244b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
12453a40ed3dSBarry Smith   PetscFunctionReturn(0);
1246289bc588SBarry Smith }
1247289bc588SBarry Smith 
12489804daf3SBarry Smith #include <petscdraw.h>
1249e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1250f1af5d2fSBarry Smith {
1251f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
12526849ba73SBarry Smith   PetscErrorCode    ierr;
1253383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1254383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1255ca15aa20SStefano Zampini   const PetscScalar *v;
1256b0a32e0cSBarry Smith   PetscViewer       viewer;
1257b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1258f3ef73ceSBarry Smith   PetscViewerFormat format;
1259f1af5d2fSBarry Smith 
1260f1af5d2fSBarry Smith   PetscFunctionBegin;
1261f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1262b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1263b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1264f1af5d2fSBarry Smith 
1265f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1266ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1267fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1268383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1269f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1270f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1271383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1272f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1273f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1274f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1275ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1276ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1277ca15aa20SStefano Zampini         else continue;
1278b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1279f1af5d2fSBarry Smith       }
1280f1af5d2fSBarry Smith     }
1281383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1282f1af5d2fSBarry Smith   } else {
1283f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1284f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1285b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1286b05fc000SLisandro Dalcin     PetscDraw popup;
1287b05fc000SLisandro Dalcin 
1288f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1289f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1290f1af5d2fSBarry Smith     }
1291383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1292b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
129345f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1294383922c3SLisandro Dalcin 
1295383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1296f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1297f1af5d2fSBarry Smith       x_l = j;
1298f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1299f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1300f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1301f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1302b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1303b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1304f1af5d2fSBarry Smith       }
1305f1af5d2fSBarry Smith     }
1306383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1307f1af5d2fSBarry Smith   }
1308ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1309f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1310f1af5d2fSBarry Smith }
1311f1af5d2fSBarry Smith 
1312e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1313f1af5d2fSBarry Smith {
1314b0a32e0cSBarry Smith   PetscDraw      draw;
1315ace3abfcSBarry Smith   PetscBool      isnull;
1316329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1317dfbe8321SBarry Smith   PetscErrorCode ierr;
1318f1af5d2fSBarry Smith 
1319f1af5d2fSBarry Smith   PetscFunctionBegin;
1320b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1321b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1322abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1323f1af5d2fSBarry Smith 
1324d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1325f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1326b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1327832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1328b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
13290298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1330832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1331f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1332f1af5d2fSBarry Smith }
1333f1af5d2fSBarry Smith 
1334dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1335932b0c3eSLois Curfman McInnes {
1336dfbe8321SBarry Smith   PetscErrorCode ierr;
1337ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1338932b0c3eSLois Curfman McInnes 
13393a40ed3dSBarry Smith   PetscFunctionBegin;
1340251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1341251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1342251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
13430f5bd95cSBarry Smith 
1344c45a1595SBarry Smith   if (iascii) {
1345c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
13460f5bd95cSBarry Smith   } else if (isbinary) {
1347637a0070SStefano Zampini     ierr = MatView_Dense_Binary(A,viewer);CHKERRQ(ierr);
1348f1af5d2fSBarry Smith   } else if (isdraw) {
1349f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1350932b0c3eSLois Curfman McInnes   }
13513a40ed3dSBarry Smith   PetscFunctionReturn(0);
1352932b0c3eSLois Curfman McInnes }
1353289bc588SBarry Smith 
1354637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array)
1355d3042a70SBarry Smith {
1356d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1357d3042a70SBarry Smith 
1358d3042a70SBarry Smith   PetscFunctionBegin;
1359*6947451fSStefano Zampini   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec first");
1360d3042a70SBarry Smith   a->unplacedarray       = a->v;
1361d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1362d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1363637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1364ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1365c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1366ca15aa20SStefano Zampini #endif
1367d3042a70SBarry Smith   PetscFunctionReturn(0);
1368d3042a70SBarry Smith }
1369d3042a70SBarry Smith 
1370d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1371d3042a70SBarry Smith {
1372d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1373d3042a70SBarry Smith 
1374d3042a70SBarry Smith   PetscFunctionBegin;
1375*6947451fSStefano Zampini   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec first");
1376d3042a70SBarry Smith   a->v             = a->unplacedarray;
1377d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1378d3042a70SBarry Smith   a->unplacedarray = NULL;
1379ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1380c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1381ca15aa20SStefano Zampini #endif
1382d3042a70SBarry Smith   PetscFunctionReturn(0);
1383d3042a70SBarry Smith }
1384d3042a70SBarry Smith 
1385ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1386289bc588SBarry Smith {
1387ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1388dfbe8321SBarry Smith   PetscErrorCode ierr;
138990f02eecSBarry Smith 
13903a40ed3dSBarry Smith   PetscFunctionBegin;
1391aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1392d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1393a5a9c739SBarry Smith #endif
139405b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1395a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1396abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
13976857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1398637a0070SStefano Zampini   if (!l->unplaced_user_alloc) {ierr = PetscFree(l->unplacedarray);CHKERRQ(ierr);}
1399*6947451fSStefano Zampini   ierr = VecDestroy(&l->cvec);CHKERRQ(ierr);
1400bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1401dbd8c25aSHong Zhang 
1402dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
140349a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1404bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
140552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
1406d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1407d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
140852c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL);CHKERRQ(ierr);
140952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL);CHKERRQ(ierr);
1410*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayWrite_C",NULL);CHKERRQ(ierr);
1411*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayWrite_C",NULL);CHKERRQ(ierr);
14128baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
14138baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
14148baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
14158baccfbdSHong Zhang #endif
14162bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
14172bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL);CHKERRQ(ierr);
14184222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL);CHKERRQ(ierr);
14194222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL);CHKERRQ(ierr);
14204222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaijcusparse_seqdense_C",NULL);CHKERRQ(ierr);
14212bf066beSStefano Zampini #endif
1422bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
14234222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14244222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL);CHKERRQ(ierr);
1425bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1426bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14274222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1428a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1429a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
14304222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
1431c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
1432c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
143352c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
143452c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
143552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
143652c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
143752c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
143852c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
143952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_nest_seqdense_C",NULL);CHKERRQ(ierr);
144052c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_nest_seqdense_C",NULL);CHKERRQ(ierr);
144152c5f739Sprj- 
14423bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14433bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
144452c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
144552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",NULL);CHKERRQ(ierr);
144652c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
144752c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",NULL);CHKERRQ(ierr);
144852c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
144952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",NULL);CHKERRQ(ierr);
145086aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
145186aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
1452*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVec_C",NULL);CHKERRQ(ierr);
1453*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVec_C",NULL);CHKERRQ(ierr);
1454*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecRead_C",NULL);CHKERRQ(ierr);
1455*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecRead_C",NULL);CHKERRQ(ierr);
1456*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecWrite_C",NULL);CHKERRQ(ierr);
1457*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecWrite_C",NULL);CHKERRQ(ierr);
14583a40ed3dSBarry Smith   PetscFunctionReturn(0);
1459289bc588SBarry Smith }
1460289bc588SBarry Smith 
1461e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1462289bc588SBarry Smith {
1463c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
14646849ba73SBarry Smith   PetscErrorCode ierr;
146513f74950SBarry Smith   PetscInt       k,j,m,n,M;
146687828ca2SBarry Smith   PetscScalar    *v,tmp;
146748b35521SBarry Smith 
14683a40ed3dSBarry Smith   PetscFunctionBegin;
1469ca15aa20SStefano Zampini   m = A->rmap->n; M = mat->lda; n = A->cmap->n;
14702847e3fdSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX && m == n) { /* in place transpose */
1471ca15aa20SStefano Zampini     ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1472d3e5ee88SLois Curfman McInnes     for (j=0; j<m; j++) {
1473289bc588SBarry Smith       for (k=0; k<j; k++) {
14741b807ce4Svictorle         tmp        = v[j + k*M];
14751b807ce4Svictorle         v[j + k*M] = v[k + j*M];
14761b807ce4Svictorle         v[k + j*M] = tmp;
1477289bc588SBarry Smith       }
1478289bc588SBarry Smith     }
1479ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
14803a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1481d3e5ee88SLois Curfman McInnes     Mat          tmat;
1482ec8511deSBarry Smith     Mat_SeqDense *tmatd;
148387828ca2SBarry Smith     PetscScalar  *v2;
1484af36a384SStefano Zampini     PetscInt     M2;
1485ea709b57SSatish Balay 
14862847e3fdSStefano Zampini     if (reuse != MAT_REUSE_MATRIX) {
1487ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1488d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
14897adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
14900298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1491ca15aa20SStefano Zampini     } else tmat = *matout;
1492ca15aa20SStefano Zampini 
1493ca15aa20SStefano Zampini     ierr  = MatDenseGetArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
1494ca15aa20SStefano Zampini     ierr  = MatDenseGetArray(tmat,&v2);CHKERRQ(ierr);
1495ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1496ca15aa20SStefano Zampini     M2    = tmatd->lda;
1497d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1498af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1499d3e5ee88SLois Curfman McInnes     }
1500ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(tmat,&v2);CHKERRQ(ierr);
1501ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
15026d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15036d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15042847e3fdSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) *matout = tmat;
15052847e3fdSStefano Zampini     else {
15062847e3fdSStefano Zampini       ierr = MatHeaderMerge(A,&tmat);CHKERRQ(ierr);
15072847e3fdSStefano Zampini     }
150848b35521SBarry Smith   }
15093a40ed3dSBarry Smith   PetscFunctionReturn(0);
1510289bc588SBarry Smith }
1511289bc588SBarry Smith 
1512e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1513289bc588SBarry Smith {
1514c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1515c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1516ca15aa20SStefano Zampini   PetscInt          i;
1517ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
1518ca15aa20SStefano Zampini   PetscErrorCode    ierr;
15199ea5d5aeSSatish Balay 
15203a40ed3dSBarry Smith   PetscFunctionBegin;
1521d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1522d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1523ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A1,&v1);CHKERRQ(ierr);
1524ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A2,&v2);CHKERRQ(ierr);
1525ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
1526ca15aa20SStefano Zampini     ierr = PetscArraycmp(v1,v2,A1->rmap->n,flg);CHKERRQ(ierr);
1527ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1528ca15aa20SStefano Zampini     v1 += mat1->lda;
1529ca15aa20SStefano Zampini     v2 += mat2->lda;
15301b807ce4Svictorle   }
1531ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A1,&v1);CHKERRQ(ierr);
1532ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A2,&v2);CHKERRQ(ierr);
153377c4ece6SBarry Smith   *flg = PETSC_TRUE;
15343a40ed3dSBarry Smith   PetscFunctionReturn(0);
1535289bc588SBarry Smith }
1536289bc588SBarry Smith 
1537e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1538289bc588SBarry Smith {
1539c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
154013f74950SBarry Smith   PetscInt          i,n,len;
1541ca15aa20SStefano Zampini   PetscScalar       *x;
1542ca15aa20SStefano Zampini   const PetscScalar *vv;
1543ca15aa20SStefano Zampini   PetscErrorCode    ierr;
154444cd7ae7SLois Curfman McInnes 
15453a40ed3dSBarry Smith   PetscFunctionBegin;
15467a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
15471ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1548d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1549ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1550e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
155144cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1552ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1553289bc588SBarry Smith   }
1554ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
15551ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
15563a40ed3dSBarry Smith   PetscFunctionReturn(0);
1557289bc588SBarry Smith }
1558289bc588SBarry Smith 
1559e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1560289bc588SBarry Smith {
1561c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1562f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1563ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1564dfbe8321SBarry Smith   PetscErrorCode    ierr;
1565d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
156655659b69SBarry Smith 
15673a40ed3dSBarry Smith   PetscFunctionBegin;
1568ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&vv);CHKERRQ(ierr);
156928988994SBarry Smith   if (ll) {
15707a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1571f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1572e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1573da3a660dSBarry Smith     for (i=0; i<m; i++) {
1574da3a660dSBarry Smith       x = l[i];
1575ca15aa20SStefano Zampini       v = vv + i;
1576b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1577da3a660dSBarry Smith     }
1578f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1579eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1580da3a660dSBarry Smith   }
158128988994SBarry Smith   if (rr) {
15827a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1583f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1584e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1585da3a660dSBarry Smith     for (i=0; i<n; i++) {
1586da3a660dSBarry Smith       x = r[i];
1587ca15aa20SStefano Zampini       v = vv + i*mat->lda;
15882205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1589da3a660dSBarry Smith     }
1590f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1591eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1592da3a660dSBarry Smith   }
1593ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&vv);CHKERRQ(ierr);
15943a40ed3dSBarry Smith   PetscFunctionReturn(0);
1595289bc588SBarry Smith }
1596289bc588SBarry Smith 
1597ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1598289bc588SBarry Smith {
1599c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1600ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1601329f5518SBarry Smith   PetscReal         sum  = 0.0;
1602d0f46423SBarry Smith   PetscInt          lda  =mat->lda,m=A->rmap->n,i,j;
1603efee365bSSatish Balay   PetscErrorCode    ierr;
160455659b69SBarry Smith 
16053a40ed3dSBarry Smith   PetscFunctionBegin;
1606ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
1607ca15aa20SStefano Zampini   v    = vv;
1608289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1609a5ce6ee0Svictorle     if (lda>m) {
1610d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1611ca15aa20SStefano Zampini         v = vv+j*lda;
1612a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1613a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1614a5ce6ee0Svictorle         }
1615a5ce6ee0Svictorle       }
1616a5ce6ee0Svictorle     } else {
1617570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1618570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1619570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1620570b7f6dSBarry Smith     }
1621570b7f6dSBarry Smith #else
1622d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1623329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1624289bc588SBarry Smith       }
1625a5ce6ee0Svictorle     }
16268f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1627570b7f6dSBarry Smith #endif
1628dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16293a40ed3dSBarry Smith   } else if (type == NORM_1) {
1630064f8208SBarry Smith     *nrm = 0.0;
1631d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1632ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
1633289bc588SBarry Smith       sum = 0.0;
1634d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
163533a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1636289bc588SBarry Smith       }
1637064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1638289bc588SBarry Smith     }
1639eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16403a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1641064f8208SBarry Smith     *nrm = 0.0;
1642d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1643ca15aa20SStefano Zampini       v   = vv + j;
1644289bc588SBarry Smith       sum = 0.0;
1645d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
16461b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1647289bc588SBarry Smith       }
1648064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1649289bc588SBarry Smith     }
1650eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1651e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
1652ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
16533a40ed3dSBarry Smith   PetscFunctionReturn(0);
1654289bc588SBarry Smith }
1655289bc588SBarry Smith 
1656e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1657289bc588SBarry Smith {
1658c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
165963ba0a88SBarry Smith   PetscErrorCode ierr;
166067e560aaSBarry Smith 
16613a40ed3dSBarry Smith   PetscFunctionBegin;
1662b5a2b587SKris Buschelman   switch (op) {
1663b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
16644e0d8c25SBarry Smith     aij->roworiented = flg;
1665b5a2b587SKris Buschelman     break;
1666512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1667b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
16683971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
16694e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
167013fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1671b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1672b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
16730f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
16745021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
1675071fcb05SBarry Smith   case MAT_SORTED_FULL:
16765021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
16775021d80fSJed Brown     break;
16785021d80fSJed Brown   case MAT_SPD:
167977e54ba9SKris Buschelman   case MAT_SYMMETRIC:
168077e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
16819a4540c5SBarry Smith   case MAT_HERMITIAN:
16829a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
16835021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
168477e54ba9SKris Buschelman     break;
1685b5a2b587SKris Buschelman   default:
1686e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
16873a40ed3dSBarry Smith   }
16883a40ed3dSBarry Smith   PetscFunctionReturn(0);
1689289bc588SBarry Smith }
1690289bc588SBarry Smith 
1691e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
16926f0a148fSBarry Smith {
1693ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
16946849ba73SBarry Smith   PetscErrorCode ierr;
1695d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
1696ca15aa20SStefano Zampini   PetscScalar    *v;
16973a40ed3dSBarry Smith 
16983a40ed3dSBarry Smith   PetscFunctionBegin;
1699ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1700a5ce6ee0Svictorle   if (lda>m) {
1701d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1702ca15aa20SStefano Zampini       ierr = PetscArrayzero(v+j*lda,m);CHKERRQ(ierr);
1703a5ce6ee0Svictorle     }
1704a5ce6ee0Svictorle   } else {
1705ca15aa20SStefano Zampini     ierr = PetscArrayzero(v,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
1706a5ce6ee0Svictorle   }
1707ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17083a40ed3dSBarry Smith   PetscFunctionReturn(0);
17096f0a148fSBarry Smith }
17106f0a148fSBarry Smith 
1711e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
17126f0a148fSBarry Smith {
171397b48c8fSBarry Smith   PetscErrorCode    ierr;
1714ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1715b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
1716ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
171797b48c8fSBarry Smith   const PetscScalar *xx;
171855659b69SBarry Smith 
17193a40ed3dSBarry Smith   PetscFunctionBegin;
172076bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1721b9679d65SBarry Smith     for (i=0; i<N; i++) {
1722b9679d65SBarry Smith       if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1723b9679d65SBarry 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);
1724b9679d65SBarry Smith     }
172576bd3646SJed Brown   }
1726ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1727b9679d65SBarry Smith 
172897b48c8fSBarry Smith   /* fix right hand side if needed */
172997b48c8fSBarry Smith   if (x && b) {
173097b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
173197b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
17322205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
173397b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
173497b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
173597b48c8fSBarry Smith   }
173697b48c8fSBarry Smith 
1737ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
17386f0a148fSBarry Smith   for (i=0; i<N; i++) {
1739ca15aa20SStefano Zampini     slot = v + rows[i];
1740b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
17416f0a148fSBarry Smith   }
1742f4df32b1SMatthew Knepley   if (diag != 0.0) {
1743b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
17446f0a148fSBarry Smith     for (i=0; i<N; i++) {
1745ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1746f4df32b1SMatthew Knepley       *slot = diag;
17476f0a148fSBarry Smith     }
17486f0a148fSBarry Smith   }
1749ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17503a40ed3dSBarry Smith   PetscFunctionReturn(0);
17516f0a148fSBarry Smith }
1752557bce09SLois Curfman McInnes 
175349a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
175449a6ff4bSBarry Smith {
175549a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
175649a6ff4bSBarry Smith 
175749a6ff4bSBarry Smith   PetscFunctionBegin;
175849a6ff4bSBarry Smith   *lda = mat->lda;
175949a6ff4bSBarry Smith   PetscFunctionReturn(0);
176049a6ff4bSBarry Smith }
176149a6ff4bSBarry Smith 
1762637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array)
176364e87e97SBarry Smith {
1764c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
17653a40ed3dSBarry Smith 
17663a40ed3dSBarry Smith   PetscFunctionBegin;
176764e87e97SBarry Smith   *array = mat->v;
17683a40ed3dSBarry Smith   PetscFunctionReturn(0);
176964e87e97SBarry Smith }
17700754003eSLois Curfman McInnes 
1771637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array)
1772ff14e315SSatish Balay {
17733a40ed3dSBarry Smith   PetscFunctionBegin;
1774637a0070SStefano Zampini   *array = NULL;
17753a40ed3dSBarry Smith   PetscFunctionReturn(0);
1776ff14e315SSatish Balay }
17770754003eSLois Curfman McInnes 
1778dec5eb66SMatthew G Knepley /*@C
177949a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
178049a6ff4bSBarry Smith 
178149a6ff4bSBarry Smith    Logically Collective on Mat
178249a6ff4bSBarry Smith 
178349a6ff4bSBarry Smith    Input Parameter:
178449a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
178549a6ff4bSBarry Smith 
178649a6ff4bSBarry Smith    Output Parameter:
178749a6ff4bSBarry Smith .   lda - the leading dimension
178849a6ff4bSBarry Smith 
178949a6ff4bSBarry Smith    Level: intermediate
179049a6ff4bSBarry Smith 
179149a6ff4bSBarry Smith .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatSeqDenseSetLDA()
179249a6ff4bSBarry Smith @*/
179349a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
179449a6ff4bSBarry Smith {
179549a6ff4bSBarry Smith   PetscErrorCode ierr;
179649a6ff4bSBarry Smith 
179749a6ff4bSBarry Smith   PetscFunctionBegin;
179849a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
179949a6ff4bSBarry Smith   PetscFunctionReturn(0);
180049a6ff4bSBarry Smith }
180149a6ff4bSBarry Smith 
180249a6ff4bSBarry Smith /*@C
1803*6947451fSStefano Zampini    MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored
180473a71a0fSBarry Smith 
18058572280aSBarry Smith    Logically Collective on Mat
180673a71a0fSBarry Smith 
180773a71a0fSBarry Smith    Input Parameter:
1808*6947451fSStefano Zampini .  mat - a dense matrix
180973a71a0fSBarry Smith 
181073a71a0fSBarry Smith    Output Parameter:
181173a71a0fSBarry Smith .   array - pointer to the data
181273a71a0fSBarry Smith 
181373a71a0fSBarry Smith    Level: intermediate
181473a71a0fSBarry Smith 
1815*6947451fSStefano Zampini .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
181673a71a0fSBarry Smith @*/
18178c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
181873a71a0fSBarry Smith {
181973a71a0fSBarry Smith   PetscErrorCode ierr;
182073a71a0fSBarry Smith 
182173a71a0fSBarry Smith   PetscFunctionBegin;
18228c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
182373a71a0fSBarry Smith   PetscFunctionReturn(0);
182473a71a0fSBarry Smith }
182573a71a0fSBarry Smith 
1826dec5eb66SMatthew G Knepley /*@C
1827579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
182873a71a0fSBarry Smith 
18298572280aSBarry Smith    Logically Collective on Mat
18308572280aSBarry Smith 
18318572280aSBarry Smith    Input Parameters:
1832*6947451fSStefano Zampini +  mat - a dense matrix
1833a2b725a8SWilliam Gropp -  array - pointer to the data
18348572280aSBarry Smith 
18358572280aSBarry Smith    Level: intermediate
18368572280aSBarry Smith 
1837*6947451fSStefano Zampini .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
18388572280aSBarry Smith @*/
18398572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
18408572280aSBarry Smith {
18418572280aSBarry Smith   PetscErrorCode ierr;
18428572280aSBarry Smith 
18438572280aSBarry Smith   PetscFunctionBegin;
18448572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
18458572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
1846637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1847637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1848637a0070SStefano Zampini #endif
18498572280aSBarry Smith   PetscFunctionReturn(0);
18508572280aSBarry Smith }
18518572280aSBarry Smith 
18528572280aSBarry Smith /*@C
1853*6947451fSStefano Zampini    MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored
18548572280aSBarry Smith 
18558572280aSBarry Smith    Not Collective
18568572280aSBarry Smith 
18578572280aSBarry Smith    Input Parameter:
1858*6947451fSStefano Zampini .  mat - a dense matrix
18598572280aSBarry Smith 
18608572280aSBarry Smith    Output Parameter:
18618572280aSBarry Smith .   array - pointer to the data
18628572280aSBarry Smith 
18638572280aSBarry Smith    Level: intermediate
18648572280aSBarry Smith 
1865*6947451fSStefano Zampini .seealso: MatDenseRestoreArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
18668572280aSBarry Smith @*/
18678572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
18688572280aSBarry Smith {
18698572280aSBarry Smith   PetscErrorCode ierr;
18708572280aSBarry Smith 
18718572280aSBarry Smith   PetscFunctionBegin;
18728572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
18738572280aSBarry Smith   PetscFunctionReturn(0);
18748572280aSBarry Smith }
18758572280aSBarry Smith 
18768572280aSBarry Smith /*@C
1877*6947451fSStefano Zampini    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead()
18788572280aSBarry Smith 
187973a71a0fSBarry Smith    Not Collective
188073a71a0fSBarry Smith 
188173a71a0fSBarry Smith    Input Parameters:
1882*6947451fSStefano Zampini +  mat - a dense matrix
1883a2b725a8SWilliam Gropp -  array - pointer to the data
188473a71a0fSBarry Smith 
188573a71a0fSBarry Smith    Level: intermediate
188673a71a0fSBarry Smith 
1887*6947451fSStefano Zampini .seealso: MatDenseGetArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
188873a71a0fSBarry Smith @*/
18898572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
189073a71a0fSBarry Smith {
189173a71a0fSBarry Smith   PetscErrorCode ierr;
189273a71a0fSBarry Smith 
189373a71a0fSBarry Smith   PetscFunctionBegin;
18948572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
189573a71a0fSBarry Smith   PetscFunctionReturn(0);
189673a71a0fSBarry Smith }
189773a71a0fSBarry Smith 
1898*6947451fSStefano Zampini /*@C
1899*6947451fSStefano Zampini    MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored
1900*6947451fSStefano Zampini 
1901*6947451fSStefano Zampini    Not Collective
1902*6947451fSStefano Zampini 
1903*6947451fSStefano Zampini    Input Parameter:
1904*6947451fSStefano Zampini .  mat - a dense matrix
1905*6947451fSStefano Zampini 
1906*6947451fSStefano Zampini    Output Parameter:
1907*6947451fSStefano Zampini .   array - pointer to the data
1908*6947451fSStefano Zampini 
1909*6947451fSStefano Zampini    Level: intermediate
1910*6947451fSStefano Zampini 
1911*6947451fSStefano Zampini .seealso: MatDenseRestoreArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
1912*6947451fSStefano Zampini @*/
1913*6947451fSStefano Zampini PetscErrorCode  MatDenseGetArrayWrite(Mat A,PetscScalar **array)
1914*6947451fSStefano Zampini {
1915*6947451fSStefano Zampini   PetscErrorCode ierr;
1916*6947451fSStefano Zampini 
1917*6947451fSStefano Zampini   PetscFunctionBegin;
1918*6947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
1919*6947451fSStefano Zampini   PetscFunctionReturn(0);
1920*6947451fSStefano Zampini }
1921*6947451fSStefano Zampini 
1922*6947451fSStefano Zampini /*@C
1923*6947451fSStefano Zampini    MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite()
1924*6947451fSStefano Zampini 
1925*6947451fSStefano Zampini    Not Collective
1926*6947451fSStefano Zampini 
1927*6947451fSStefano Zampini    Input Parameters:
1928*6947451fSStefano Zampini +  mat - a dense matrix
1929*6947451fSStefano Zampini -  array - pointer to the data
1930*6947451fSStefano Zampini 
1931*6947451fSStefano Zampini    Level: intermediate
1932*6947451fSStefano Zampini 
1933*6947451fSStefano Zampini .seealso: MatDenseGetArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
1934*6947451fSStefano Zampini @*/
1935*6947451fSStefano Zampini PetscErrorCode  MatDenseRestoreArrayWrite(Mat A,PetscScalar **array)
1936*6947451fSStefano Zampini {
1937*6947451fSStefano Zampini   PetscErrorCode ierr;
1938*6947451fSStefano Zampini 
1939*6947451fSStefano Zampini   PetscFunctionBegin;
1940*6947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
1941*6947451fSStefano Zampini   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
1942*6947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1943*6947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1944*6947451fSStefano Zampini #endif
1945*6947451fSStefano Zampini   PetscFunctionReturn(0);
1946*6947451fSStefano Zampini }
1947*6947451fSStefano Zampini 
19487dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
19490754003eSLois Curfman McInnes {
1950c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
19516849ba73SBarry Smith   PetscErrorCode ierr;
1952ca15aa20SStefano Zampini   PetscInt       i,j,nrows,ncols,blda;
19535d0c19d7SBarry Smith   const PetscInt *irow,*icol;
195487828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
19550754003eSLois Curfman McInnes   Mat            newmat;
19560754003eSLois Curfman McInnes 
19573a40ed3dSBarry Smith   PetscFunctionBegin;
195878b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
195978b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1960e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1961e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
19620754003eSLois Curfman McInnes 
1963182d2002SSatish Balay   /* Check submatrixcall */
1964182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
196513f74950SBarry Smith     PetscInt n_cols,n_rows;
1966182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
196721a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
1968f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
1969c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
197021a2c019SBarry Smith     }
1971182d2002SSatish Balay     newmat = *B;
1972182d2002SSatish Balay   } else {
19730754003eSLois Curfman McInnes     /* Create and fill new matrix */
1974ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
1975f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
19767adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
19770298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1978182d2002SSatish Balay   }
1979182d2002SSatish Balay 
1980182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1981ca15aa20SStefano Zampini   ierr = MatDenseGetArray(newmat,&bv);CHKERRQ(ierr);
1982ca15aa20SStefano Zampini   ierr = MatDenseGetLDA(newmat,&blda);CHKERRQ(ierr);
1983182d2002SSatish Balay   for (i=0; i<ncols; i++) {
19846de62eeeSBarry Smith     av = v + mat->lda*icol[i];
1985ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
1986ca15aa20SStefano Zampini     bv += blda;
19870754003eSLois Curfman McInnes   }
1988ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(newmat,&bv);CHKERRQ(ierr);
1989182d2002SSatish Balay 
1990182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
19916d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19926d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19930754003eSLois Curfman McInnes 
19940754003eSLois Curfman McInnes   /* Free work space */
199578b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
199678b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1997182d2002SSatish Balay   *B   = newmat;
19983a40ed3dSBarry Smith   PetscFunctionReturn(0);
19990754003eSLois Curfman McInnes }
20000754003eSLois Curfman McInnes 
20017dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2002905e6a2fSBarry Smith {
20036849ba73SBarry Smith   PetscErrorCode ierr;
200413f74950SBarry Smith   PetscInt       i;
2005905e6a2fSBarry Smith 
20063a40ed3dSBarry Smith   PetscFunctionBegin;
2007905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2008df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
2009905e6a2fSBarry Smith   }
2010905e6a2fSBarry Smith 
2011905e6a2fSBarry Smith   for (i=0; i<n; i++) {
20127dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2013905e6a2fSBarry Smith   }
20143a40ed3dSBarry Smith   PetscFunctionReturn(0);
2015905e6a2fSBarry Smith }
2016905e6a2fSBarry Smith 
2017e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2018c0aa2d19SHong Zhang {
2019c0aa2d19SHong Zhang   PetscFunctionBegin;
2020c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2021c0aa2d19SHong Zhang }
2022c0aa2d19SHong Zhang 
2023e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2024c0aa2d19SHong Zhang {
2025c0aa2d19SHong Zhang   PetscFunctionBegin;
2026c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2027c0aa2d19SHong Zhang }
2028c0aa2d19SHong Zhang 
2029e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
20304b0e389bSBarry Smith {
20314b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
20326849ba73SBarry Smith   PetscErrorCode    ierr;
2033ca15aa20SStefano Zampini   const PetscScalar *va;
2034ca15aa20SStefano Zampini   PetscScalar       *vb;
2035d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
20363a40ed3dSBarry Smith 
20373a40ed3dSBarry Smith   PetscFunctionBegin;
203833f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
203933f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
2040cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
20413a40ed3dSBarry Smith     PetscFunctionReturn(0);
20423a40ed3dSBarry Smith   }
2043e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
2044ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&va);CHKERRQ(ierr);
2045ca15aa20SStefano Zampini   ierr = MatDenseGetArray(B,&vb);CHKERRQ(ierr);
2046a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
20470dbb7854Svictorle     for (j=0; j<n; j++) {
2048ca15aa20SStefano Zampini       ierr = PetscArraycpy(vb+j*lda2,va+j*lda1,m);CHKERRQ(ierr);
2049a5ce6ee0Svictorle     }
2050a5ce6ee0Svictorle   } else {
2051ca15aa20SStefano Zampini     ierr = PetscArraycpy(vb,va,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2052a5ce6ee0Svictorle   }
2053ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(B,&vb);CHKERRQ(ierr);
2054ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&va);CHKERRQ(ierr);
2055ca15aa20SStefano Zampini   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2056ca15aa20SStefano Zampini   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2057273d9f13SBarry Smith   PetscFunctionReturn(0);
2058273d9f13SBarry Smith }
2059273d9f13SBarry Smith 
2060e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
2061273d9f13SBarry Smith {
2062dfbe8321SBarry Smith   PetscErrorCode ierr;
2063273d9f13SBarry Smith 
2064273d9f13SBarry Smith   PetscFunctionBegin;
206518992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
206618992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
206718992e5dSStefano Zampini   if (!A->preallocated) {
2068273d9f13SBarry Smith     ierr = MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
206918992e5dSStefano Zampini   }
20703a40ed3dSBarry Smith   PetscFunctionReturn(0);
20714b0e389bSBarry Smith }
20724b0e389bSBarry Smith 
2073ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2074ba337c44SJed Brown {
2075ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2076ca15aa20SStefano Zampini   PetscScalar    *aa;
2077ca15aa20SStefano Zampini   PetscErrorCode ierr;
2078ba337c44SJed Brown 
2079ba337c44SJed Brown   PetscFunctionBegin;
2080ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2081ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2082ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2083ba337c44SJed Brown   PetscFunctionReturn(0);
2084ba337c44SJed Brown }
2085ba337c44SJed Brown 
2086ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2087ba337c44SJed Brown {
2088ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2089ca15aa20SStefano Zampini   PetscScalar    *aa;
2090ca15aa20SStefano Zampini   PetscErrorCode ierr;
2091ba337c44SJed Brown 
2092ba337c44SJed Brown   PetscFunctionBegin;
2093ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2094ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2095ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2096ba337c44SJed Brown   PetscFunctionReturn(0);
2097ba337c44SJed Brown }
2098ba337c44SJed Brown 
2099ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2100ba337c44SJed Brown {
2101ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2102ca15aa20SStefano Zampini   PetscScalar    *aa;
2103ca15aa20SStefano Zampini   PetscErrorCode ierr;
2104ba337c44SJed Brown 
2105ba337c44SJed Brown   PetscFunctionBegin;
2106ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2107ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
2108ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2109ba337c44SJed Brown   PetscFunctionReturn(0);
2110ba337c44SJed Brown }
2111284134d9SBarry Smith 
2112a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
21134222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2114a9fe9ddaSSatish Balay {
2115ee16a9a1SHong Zhang   PetscErrorCode ierr;
2116d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
2117ca15aa20SStefano Zampini   PetscBool      flg;
2118a9fe9ddaSSatish Balay 
2119ee16a9a1SHong Zhang   PetscFunctionBegin;
21204222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
2121ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
21224222ddf1SHong Zhang   ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
212318992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2124ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2125ee16a9a1SHong Zhang }
2126a9fe9ddaSSatish Balay 
2127a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2128a9fe9ddaSSatish Balay {
212952c5f739Sprj-   Mat_SeqDense       *a,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
21300805154bSBarry Smith   PetscBLASInt       m,n,k;
2131ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2132ca15aa20SStefano Zampini   PetscScalar       *cv;
2133a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2134fd4e9aacSBarry Smith   PetscBool         flg;
2135c2916339SPierre Jolivet   PetscErrorCode    (*numeric)(Mat,Mat,Mat)=NULL;
2136c2916339SPierre Jolivet   PetscErrorCode    ierr;
2137a9fe9ddaSSatish Balay 
2138a9fe9ddaSSatish Balay   PetscFunctionBegin;
2139fd4e9aacSBarry Smith   /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/
2140fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
2141c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqAIJ_SeqDense;
2142a001520aSPierre Jolivet   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQBAIJ,&flg);CHKERRQ(ierr);
2143c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqBAIJ_SeqDense;
2144c2916339SPierre Jolivet   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQSBAIJ,&flg);CHKERRQ(ierr);
2145c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_SeqSBAIJ_SeqDense;
214652c5f739Sprj-   ierr = PetscObjectTypeCompare((PetscObject)A,MATNEST,&flg);CHKERRQ(ierr);
2147c2916339SPierre Jolivet   if (flg) numeric = MatMatMultNumeric_Nest_Dense;
2148c2916339SPierre Jolivet   if (numeric) {
2149c2916339SPierre Jolivet     C->ops->matmultnumeric = numeric;
2150c2916339SPierre Jolivet     ierr = (*numeric)(A,B,C);CHKERRQ(ierr);
215152c5f739Sprj-     PetscFunctionReturn(0);
215252c5f739Sprj-   }
215352c5f739Sprj-   a = (Mat_SeqDense*)A->data;
21548208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
21558208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2156c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
215749d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
2158ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
2159ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
2160ca15aa20SStefano Zampini   ierr = MatDenseGetArray(C,&cv);CHKERRQ(ierr);
2161ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
2162ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2163ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
2164ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
2165ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(C,&cv);CHKERRQ(ierr);
2166a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2167a9fe9ddaSSatish Balay }
2168a9fe9ddaSSatish Balay 
21694222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
217069f65d41SStefano Zampini {
217169f65d41SStefano Zampini   PetscErrorCode ierr;
217269f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
2173ca15aa20SStefano Zampini   PetscBool      flg;
217469f65d41SStefano Zampini 
217569f65d41SStefano Zampini   PetscFunctionBegin;
21764222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
2177ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
21784222ddf1SHong Zhang   ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
217918992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
218069f65d41SStefano Zampini   PetscFunctionReturn(0);
218169f65d41SStefano Zampini }
218269f65d41SStefano Zampini 
218369f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
218469f65d41SStefano Zampini {
218569f65d41SStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
218669f65d41SStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
218769f65d41SStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
218869f65d41SStefano Zampini   PetscBLASInt   m,n,k;
218969f65d41SStefano Zampini   PetscScalar    _DOne=1.0,_DZero=0.0;
219069f65d41SStefano Zampini   PetscErrorCode ierr;
219169f65d41SStefano Zampini 
219269f65d41SStefano Zampini   PetscFunctionBegin;
219349d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
219449d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
219569f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
219649d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
219769f65d41SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2198ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
219969f65d41SStefano Zampini   PetscFunctionReturn(0);
220069f65d41SStefano Zampini }
220169f65d41SStefano Zampini 
22024222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2203a9fe9ddaSSatish Balay {
2204ee16a9a1SHong Zhang   PetscErrorCode ierr;
2205d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
2206ca15aa20SStefano Zampini   PetscBool      flg;
2207a9fe9ddaSSatish Balay 
2208ee16a9a1SHong Zhang   PetscFunctionBegin;
22094222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
2210ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
22114222ddf1SHong Zhang   ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
221218992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2213ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2214ee16a9a1SHong Zhang }
2215a9fe9ddaSSatish Balay 
221675648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2217a9fe9ddaSSatish Balay {
2218a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2219a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2220a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
22210805154bSBarry Smith   PetscBLASInt   m,n,k;
2222a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
2223c5df96a5SBarry Smith   PetscErrorCode ierr;
2224a9fe9ddaSSatish Balay 
2225a9fe9ddaSSatish Balay   PetscFunctionBegin;
22268208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
22278208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2228c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
222949d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
22305ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2231ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2232a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2233a9fe9ddaSSatish Balay }
2234985db425SBarry Smith 
22354222ddf1SHong Zhang /* ----------------------------------------------- */
22364222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
22374222ddf1SHong Zhang {
22384222ddf1SHong Zhang   PetscFunctionBegin;
22394222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
22404222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
22414222ddf1SHong Zhang   /* dense mat may not call MatProductSymbolic(), thus set C->ops->productnumeric here */
22424222ddf1SHong Zhang   C->ops->productnumeric  = MatProductNumeric_AB;
22434222ddf1SHong Zhang   PetscFunctionReturn(0);
22444222ddf1SHong Zhang }
22454222ddf1SHong Zhang 
22464222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
22474222ddf1SHong Zhang {
22484222ddf1SHong Zhang   PetscFunctionBegin;
22494222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
22504222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
22514222ddf1SHong Zhang   C->ops->productnumeric           = MatProductNumeric_AtB;
22524222ddf1SHong Zhang   PetscFunctionReturn(0);
22534222ddf1SHong Zhang }
22544222ddf1SHong Zhang 
22554222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
22564222ddf1SHong Zhang {
22574222ddf1SHong Zhang   PetscFunctionBegin;
22584222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
22594222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
22604222ddf1SHong Zhang   C->ops->productnumeric           = MatProductNumeric_ABt;
22614222ddf1SHong Zhang   PetscFunctionReturn(0);
22624222ddf1SHong Zhang }
22634222ddf1SHong Zhang 
22644222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_PtAP(Mat C)
22654222ddf1SHong Zhang {
22664222ddf1SHong Zhang   PetscFunctionBegin;
22674222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_Basic;
22684222ddf1SHong Zhang   PetscFunctionReturn(0);
22694222ddf1SHong Zhang }
22704222ddf1SHong Zhang 
22714222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
22724222ddf1SHong Zhang {
22734222ddf1SHong Zhang   PetscErrorCode ierr;
22744222ddf1SHong Zhang   Mat_Product    *product = C->product;
22754222ddf1SHong Zhang 
22764222ddf1SHong Zhang   PetscFunctionBegin;
22774222ddf1SHong Zhang   switch (product->type) {
22784222ddf1SHong Zhang   case MATPRODUCT_AB:
22794222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AB(C);CHKERRQ(ierr);
22804222ddf1SHong Zhang     break;
22814222ddf1SHong Zhang   case MATPRODUCT_AtB:
22824222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AtB(C);CHKERRQ(ierr);
22834222ddf1SHong Zhang     break;
22844222ddf1SHong Zhang   case MATPRODUCT_ABt:
22854222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_ABt(C);CHKERRQ(ierr);
22864222ddf1SHong Zhang     break;
22874222ddf1SHong Zhang   case MATPRODUCT_PtAP:
22884222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_PtAP(C);CHKERRQ(ierr);
22894222ddf1SHong Zhang     break;
2290544a5e07SHong Zhang   default: SETERRQ1(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProduct type %s is not supported for SeqDense and SeqDense matrices",MatProductTypes[product->type]);
22914222ddf1SHong Zhang   }
22924222ddf1SHong Zhang   PetscFunctionReturn(0);
22934222ddf1SHong Zhang }
22944222ddf1SHong Zhang /* ----------------------------------------------- */
22954222ddf1SHong Zhang 
2296e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2297985db425SBarry Smith {
2298985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2299985db425SBarry Smith   PetscErrorCode     ierr;
2300d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2301985db425SBarry Smith   PetscScalar        *x;
2302ca15aa20SStefano Zampini   const PetscScalar *aa;
2303985db425SBarry Smith 
2304985db425SBarry Smith   PetscFunctionBegin;
2305e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2306985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2307985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2308ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2309e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2310985db425SBarry Smith   for (i=0; i<m; i++) {
2311985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2312985db425SBarry Smith     for (j=1; j<n; j++) {
2313ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2314985db425SBarry Smith     }
2315985db425SBarry Smith   }
2316ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2317985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2318985db425SBarry Smith   PetscFunctionReturn(0);
2319985db425SBarry Smith }
2320985db425SBarry Smith 
2321e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2322985db425SBarry Smith {
2323985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2324985db425SBarry Smith   PetscErrorCode    ierr;
2325d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2326985db425SBarry Smith   PetscScalar       *x;
2327985db425SBarry Smith   PetscReal         atmp;
2328ca15aa20SStefano Zampini   const PetscScalar *aa;
2329985db425SBarry Smith 
2330985db425SBarry Smith   PetscFunctionBegin;
2331e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2332985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2333985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2334ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2335e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2336985db425SBarry Smith   for (i=0; i<m; i++) {
23379189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2338985db425SBarry Smith     for (j=1; j<n; j++) {
2339ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2340985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2341985db425SBarry Smith     }
2342985db425SBarry Smith   }
2343ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2344985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2345985db425SBarry Smith   PetscFunctionReturn(0);
2346985db425SBarry Smith }
2347985db425SBarry Smith 
2348e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2349985db425SBarry Smith {
2350985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2351985db425SBarry Smith   PetscErrorCode    ierr;
2352d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2353985db425SBarry Smith   PetscScalar       *x;
2354ca15aa20SStefano Zampini   const PetscScalar *aa;
2355985db425SBarry Smith 
2356985db425SBarry Smith   PetscFunctionBegin;
2357e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2358ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2359985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2360985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2361e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2362985db425SBarry Smith   for (i=0; i<m; i++) {
2363985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2364985db425SBarry Smith     for (j=1; j<n; j++) {
2365ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2366985db425SBarry Smith     }
2367985db425SBarry Smith   }
2368985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2369ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2370985db425SBarry Smith   PetscFunctionReturn(0);
2371985db425SBarry Smith }
2372985db425SBarry Smith 
2373637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
23748d0534beSBarry Smith {
23758d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
23768d0534beSBarry Smith   PetscErrorCode    ierr;
23778d0534beSBarry Smith   PetscScalar       *x;
2378ca15aa20SStefano Zampini   const PetscScalar *aa;
23798d0534beSBarry Smith 
23808d0534beSBarry Smith   PetscFunctionBegin;
2381e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2382ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
23838d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2384ca15aa20SStefano Zampini   ierr = PetscArraycpy(x,aa+col*a->lda,A->rmap->n);CHKERRQ(ierr);
23858d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2386ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
23878d0534beSBarry Smith   PetscFunctionReturn(0);
23888d0534beSBarry Smith }
23898d0534beSBarry Smith 
239052c5f739Sprj- PETSC_INTERN PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
23910716a85fSBarry Smith {
23920716a85fSBarry Smith   PetscErrorCode    ierr;
23930716a85fSBarry Smith   PetscInt          i,j,m,n;
23941683a169SBarry Smith   const PetscScalar *a;
23950716a85fSBarry Smith 
23960716a85fSBarry Smith   PetscFunctionBegin;
23970716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2398580bdb30SBarry Smith   ierr = PetscArrayzero(norms,n);CHKERRQ(ierr);
23991683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&a);CHKERRQ(ierr);
24000716a85fSBarry Smith   if (type == NORM_2) {
24010716a85fSBarry Smith     for (i=0; i<n; i++) {
24020716a85fSBarry Smith       for (j=0; j<m; j++) {
24030716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
24040716a85fSBarry Smith       }
24050716a85fSBarry Smith       a += m;
24060716a85fSBarry Smith     }
24070716a85fSBarry Smith   } else if (type == NORM_1) {
24080716a85fSBarry Smith     for (i=0; i<n; i++) {
24090716a85fSBarry Smith       for (j=0; j<m; j++) {
24100716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
24110716a85fSBarry Smith       }
24120716a85fSBarry Smith       a += m;
24130716a85fSBarry Smith     }
24140716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
24150716a85fSBarry Smith     for (i=0; i<n; i++) {
24160716a85fSBarry Smith       for (j=0; j<m; j++) {
24170716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
24180716a85fSBarry Smith       }
24190716a85fSBarry Smith       a += m;
24200716a85fSBarry Smith     }
2421ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
24221683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&a);CHKERRQ(ierr);
24230716a85fSBarry Smith   if (type == NORM_2) {
24248f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
24250716a85fSBarry Smith   }
24260716a85fSBarry Smith   PetscFunctionReturn(0);
24270716a85fSBarry Smith }
24280716a85fSBarry Smith 
242973a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
243073a71a0fSBarry Smith {
243173a71a0fSBarry Smith   PetscErrorCode ierr;
243273a71a0fSBarry Smith   PetscScalar    *a;
2433637a0070SStefano Zampini   PetscInt       lda,m,n,i,j;
243473a71a0fSBarry Smith 
243573a71a0fSBarry Smith   PetscFunctionBegin;
243673a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
2437637a0070SStefano Zampini   ierr = MatDenseGetLDA(x,&lda);CHKERRQ(ierr);
24388c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
2439637a0070SStefano Zampini   for (j=0; j<n; j++) {
2440637a0070SStefano Zampini     for (i=0; i<m; i++) {
2441637a0070SStefano Zampini       ierr = PetscRandomGetValue(rctx,a+j*lda+i);CHKERRQ(ierr);
2442637a0070SStefano Zampini     }
244373a71a0fSBarry Smith   }
24448c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
244573a71a0fSBarry Smith   PetscFunctionReturn(0);
244673a71a0fSBarry Smith }
244773a71a0fSBarry Smith 
24483b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
24493b49f96aSBarry Smith {
24503b49f96aSBarry Smith   PetscFunctionBegin;
24513b49f96aSBarry Smith   *missing = PETSC_FALSE;
24523b49f96aSBarry Smith   PetscFunctionReturn(0);
24533b49f96aSBarry Smith }
245473a71a0fSBarry Smith 
2455ca15aa20SStefano Zampini /* vals is not const */
2456af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
245786aefd0dSHong Zhang {
2458ca15aa20SStefano Zampini   PetscErrorCode ierr;
245986aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2460ca15aa20SStefano Zampini   PetscScalar    *v;
246186aefd0dSHong Zhang 
246286aefd0dSHong Zhang   PetscFunctionBegin;
246386aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2464ca15aa20SStefano Zampini   ierr  = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2465ca15aa20SStefano Zampini   *vals = v+col*a->lda;
2466ca15aa20SStefano Zampini   ierr  = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
246786aefd0dSHong Zhang   PetscFunctionReturn(0);
246886aefd0dSHong Zhang }
246986aefd0dSHong Zhang 
2470af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
247186aefd0dSHong Zhang {
247286aefd0dSHong Zhang   PetscFunctionBegin;
247386aefd0dSHong Zhang   *vals = 0; /* user cannot accidently use the array later */
247486aefd0dSHong Zhang   PetscFunctionReturn(0);
247586aefd0dSHong Zhang }
2476abc3b08eSStefano Zampini 
2477289bc588SBarry Smith /* -------------------------------------------------------------------*/
2478a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2479905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2480905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2481905e6a2fSBarry Smith                                         MatMult_SeqDense,
248297304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
24837c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
24847c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2485db4efbfdSBarry Smith                                         0,
2486db4efbfdSBarry Smith                                         0,
2487db4efbfdSBarry Smith                                         0,
2488db4efbfdSBarry Smith                                 /* 10*/ 0,
2489905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2490905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
249141f059aeSBarry Smith                                         MatSOR_SeqDense,
2492ec8511deSBarry Smith                                         MatTranspose_SeqDense,
249397304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2494905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2495905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2496905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2497905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2498c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2499c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2500905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2501905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2502d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2503db4efbfdSBarry Smith                                         0,
2504db4efbfdSBarry Smith                                         0,
2505db4efbfdSBarry Smith                                         0,
2506db4efbfdSBarry Smith                                         0,
25074994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2508273d9f13SBarry Smith                                         0,
2509905e6a2fSBarry Smith                                         0,
251073a71a0fSBarry Smith                                         0,
251173a71a0fSBarry Smith                                         0,
2512d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2513a5ae1ecdSBarry Smith                                         0,
2514a5ae1ecdSBarry Smith                                         0,
2515a5ae1ecdSBarry Smith                                         0,
2516a5ae1ecdSBarry Smith                                         0,
2517d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
25187dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2519a5ae1ecdSBarry Smith                                         0,
25204b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2521a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2522d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2523a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
25247d68702bSBarry Smith                                         MatShift_Basic,
2525a5ae1ecdSBarry Smith                                         0,
25263f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
252773a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2528a5ae1ecdSBarry Smith                                         0,
2529a5ae1ecdSBarry Smith                                         0,
2530a5ae1ecdSBarry Smith                                         0,
2531a5ae1ecdSBarry Smith                                         0,
2532d519adbfSMatthew Knepley                                 /* 54*/ 0,
2533a5ae1ecdSBarry Smith                                         0,
2534a5ae1ecdSBarry Smith                                         0,
2535a5ae1ecdSBarry Smith                                         0,
2536a5ae1ecdSBarry Smith                                         0,
2537d519adbfSMatthew Knepley                                 /* 59*/ 0,
2538e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2539e03a110bSBarry Smith                                         MatView_SeqDense,
2540357abbc8SBarry Smith                                         0,
254197304618SKris Buschelman                                         0,
2542d519adbfSMatthew Knepley                                 /* 64*/ 0,
254397304618SKris Buschelman                                         0,
254497304618SKris Buschelman                                         0,
254597304618SKris Buschelman                                         0,
254697304618SKris Buschelman                                         0,
2547d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
254897304618SKris Buschelman                                         0,
254997304618SKris Buschelman                                         0,
255097304618SKris Buschelman                                         0,
255197304618SKris Buschelman                                         0,
2552d519adbfSMatthew Knepley                                 /* 74*/ 0,
255397304618SKris Buschelman                                         0,
255497304618SKris Buschelman                                         0,
255597304618SKris Buschelman                                         0,
255697304618SKris Buschelman                                         0,
2557d519adbfSMatthew Knepley                                 /* 79*/ 0,
255897304618SKris Buschelman                                         0,
255997304618SKris Buschelman                                         0,
256097304618SKris Buschelman                                         0,
25615bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2562637a0070SStefano Zampini                                         MatIsSymmetric_SeqDense,
25631cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2564865e5f61SKris Buschelman                                         0,
2565865e5f61SKris Buschelman                                         0,
2566865e5f61SKris Buschelman                                         0,
25674222ddf1SHong Zhang                                 /* 89*/ 0,
25684222ddf1SHong Zhang                                         0,
2569a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
25704222ddf1SHong Zhang                                         0,
25714222ddf1SHong Zhang                                         0,
25724222ddf1SHong Zhang                                 /* 94*/ 0,
25734222ddf1SHong Zhang                                         0,
25744222ddf1SHong Zhang                                         0,
257569f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2576284134d9SBarry Smith                                         0,
25774222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
2578284134d9SBarry Smith                                         0,
2579284134d9SBarry Smith                                         0,
2580ba337c44SJed Brown                                         MatConjugate_SeqDense,
2581f73d5cc4SBarry Smith                                         0,
2582ba337c44SJed Brown                                 /*104*/ 0,
2583ba337c44SJed Brown                                         MatRealPart_SeqDense,
2584ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2585985db425SBarry Smith                                         0,
2586985db425SBarry Smith                                         0,
25878208b9aeSStefano Zampini                                 /*109*/ 0,
2588985db425SBarry Smith                                         0,
25898d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2590aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
25913b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2592aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2593aabbc4fbSShri Abhyankar                                         0,
2594aabbc4fbSShri Abhyankar                                         0,
2595aabbc4fbSShri Abhyankar                                         0,
2596aabbc4fbSShri Abhyankar                                         0,
2597aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2598aabbc4fbSShri Abhyankar                                         0,
2599aabbc4fbSShri Abhyankar                                         0,
26000716a85fSBarry Smith                                         0,
26010716a85fSBarry Smith                                         0,
26020716a85fSBarry Smith                                 /*124*/ 0,
26035df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
26045df89d91SHong Zhang                                         0,
26055df89d91SHong Zhang                                         0,
26065df89d91SHong Zhang                                         0,
26075df89d91SHong Zhang                                 /*129*/ 0,
26084222ddf1SHong Zhang                                         0,
26094222ddf1SHong Zhang                                         0,
261075648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
26113964eb88SJed Brown                                         0,
26123964eb88SJed Brown                                 /*134*/ 0,
26133964eb88SJed Brown                                         0,
26143964eb88SJed Brown                                         0,
26153964eb88SJed Brown                                         0,
26163964eb88SJed Brown                                         0,
26173964eb88SJed Brown                                 /*139*/ 0,
2618f9426fe0SMark Adams                                         0,
2619d528f656SJakub Kruzik                                         0,
2620d528f656SJakub Kruzik                                         0,
2621d528f656SJakub Kruzik                                         0,
26224222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
26234222ddf1SHong Zhang                                 /*145*/ 0,
26244222ddf1SHong Zhang                                         0,
26254222ddf1SHong Zhang                                         0
2626985db425SBarry Smith };
262790ace30eSBarry Smith 
26284b828684SBarry Smith /*@C
2629fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2630d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2631d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2632289bc588SBarry Smith 
2633d083f849SBarry Smith    Collective
2634db81eaa0SLois Curfman McInnes 
263520563c6bSBarry Smith    Input Parameters:
2636db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
26370c775827SLois Curfman McInnes .  m - number of rows
263818f449edSLois Curfman McInnes .  n - number of columns
26390298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2640dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
264120563c6bSBarry Smith 
264220563c6bSBarry Smith    Output Parameter:
264344cd7ae7SLois Curfman McInnes .  A - the matrix
264420563c6bSBarry Smith 
2645b259b22eSLois Curfman McInnes    Notes:
264618f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
264718f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
26480298fd71SBarry Smith    set data=NULL.
264918f449edSLois Curfman McInnes 
2650027ccd11SLois Curfman McInnes    Level: intermediate
2651027ccd11SLois Curfman McInnes 
265269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
265320563c6bSBarry Smith @*/
26547087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2655289bc588SBarry Smith {
2656dfbe8321SBarry Smith   PetscErrorCode ierr;
26573b2fbd54SBarry Smith 
26583a40ed3dSBarry Smith   PetscFunctionBegin;
2659f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2660f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2661273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2662273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2663273d9f13SBarry Smith   PetscFunctionReturn(0);
2664273d9f13SBarry Smith }
2665273d9f13SBarry Smith 
2666273d9f13SBarry Smith /*@C
2667273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2668273d9f13SBarry Smith 
2669d083f849SBarry Smith    Collective
2670273d9f13SBarry Smith 
2671273d9f13SBarry Smith    Input Parameters:
26721c4f3114SJed Brown +  B - the matrix
26730298fd71SBarry Smith -  data - the array (or NULL)
2674273d9f13SBarry Smith 
2675273d9f13SBarry Smith    Notes:
2676273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2677273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2678284134d9SBarry Smith    need not call this routine.
2679273d9f13SBarry Smith 
2680273d9f13SBarry Smith    Level: intermediate
2681273d9f13SBarry Smith 
268269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA()
2683867c911aSBarry Smith 
2684273d9f13SBarry Smith @*/
26857087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2686273d9f13SBarry Smith {
26874ac538c5SBarry Smith   PetscErrorCode ierr;
2688a23d5eceSKris Buschelman 
2689a23d5eceSKris Buschelman   PetscFunctionBegin;
26904ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2691a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2692a23d5eceSKris Buschelman }
2693a23d5eceSKris Buschelman 
26947087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2695a23d5eceSKris Buschelman {
2696273d9f13SBarry Smith   Mat_SeqDense   *b;
2697dfbe8321SBarry Smith   PetscErrorCode ierr;
2698273d9f13SBarry Smith 
2699273d9f13SBarry Smith   PetscFunctionBegin;
2700273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2701a868139aSShri Abhyankar 
270234ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
270334ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
270434ef9618SShri Abhyankar 
2705273d9f13SBarry Smith   b       = (Mat_SeqDense*)B->data;
270686d161a7SShri Abhyankar   b->Mmax = B->rmap->n;
270786d161a7SShri Abhyankar   b->Nmax = B->cmap->n;
270886d161a7SShri Abhyankar   if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n;
270986d161a7SShri Abhyankar 
2710220afb94SBarry Smith   ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr);
27119e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
27129e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2713e92229d0SSatish Balay     ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr);
27143bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
27152205254eSKarl Rupp 
27169e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2717273d9f13SBarry Smith   } else { /* user-allocated storage */
27189e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2719273d9f13SBarry Smith     b->v          = data;
2720273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2721273d9f13SBarry Smith   }
27220450473dSBarry Smith   B->assembled = PETSC_TRUE;
2723273d9f13SBarry Smith   PetscFunctionReturn(0);
2724273d9f13SBarry Smith }
2725273d9f13SBarry Smith 
272665b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2727cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
27288baccfbdSHong Zhang {
2729d77f618aSHong Zhang   Mat               mat_elemental;
2730d77f618aSHong Zhang   PetscErrorCode    ierr;
27311683a169SBarry Smith   const PetscScalar *array;
27321683a169SBarry Smith   PetscScalar       *v_colwise;
2733d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2734d77f618aSHong Zhang 
27358baccfbdSHong Zhang   PetscFunctionBegin;
2736d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
27371683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&array);CHKERRQ(ierr);
2738d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2739d77f618aSHong Zhang   k = 0;
2740d77f618aSHong Zhang   for (j=0; j<N; j++) {
2741d77f618aSHong Zhang     cols[j] = j;
2742d77f618aSHong Zhang     for (i=0; i<M; i++) {
2743d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2744d77f618aSHong Zhang     }
2745d77f618aSHong Zhang   }
2746d77f618aSHong Zhang   for (i=0; i<M; i++) {
2747d77f618aSHong Zhang     rows[i] = i;
2748d77f618aSHong Zhang   }
27491683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&array);CHKERRQ(ierr);
2750d77f618aSHong Zhang 
2751d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2752d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2753d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2754d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2755d77f618aSHong Zhang 
2756d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2757d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2758d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2759d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2760d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2761d77f618aSHong Zhang 
2762511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
276328be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2764d77f618aSHong Zhang   } else {
2765d77f618aSHong Zhang     *newmat = mat_elemental;
2766d77f618aSHong Zhang   }
27678baccfbdSHong Zhang   PetscFunctionReturn(0);
27688baccfbdSHong Zhang }
276965b80a83SHong Zhang #endif
27708baccfbdSHong Zhang 
27711b807ce4Svictorle /*@C
27721b807ce4Svictorle   MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array
27731b807ce4Svictorle 
27741b807ce4Svictorle   Input parameter:
27751b807ce4Svictorle + A - the matrix
27761b807ce4Svictorle - lda - the leading dimension
27771b807ce4Svictorle 
27781b807ce4Svictorle   Notes:
2779867c911aSBarry Smith   This routine is to be used in conjunction with MatSeqDenseSetPreallocation();
27801b807ce4Svictorle   it asserts that the preallocation has a leading dimension (the LDA parameter
27811b807ce4Svictorle   of Blas and Lapack fame) larger than M, the first dimension of the matrix.
27821b807ce4Svictorle 
27831b807ce4Svictorle   Level: intermediate
27841b807ce4Svictorle 
2785284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize()
2786867c911aSBarry Smith 
27871b807ce4Svictorle @*/
27887087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetLDA(Mat B,PetscInt lda)
27891b807ce4Svictorle {
27901b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
279121a2c019SBarry Smith 
27921b807ce4Svictorle   PetscFunctionBegin;
2793e32f2f54SBarry 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);
27941b807ce4Svictorle   b->lda       = lda;
279521a2c019SBarry Smith   b->changelda = PETSC_FALSE;
279621a2c019SBarry Smith   b->Mmax      = PetscMax(b->Mmax,lda);
27971b807ce4Svictorle   PetscFunctionReturn(0);
27981b807ce4Svictorle }
27991b807ce4Svictorle 
2800d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
2801d528f656SJakub Kruzik {
2802d528f656SJakub Kruzik   PetscErrorCode ierr;
2803d528f656SJakub Kruzik   PetscMPIInt    size;
2804d528f656SJakub Kruzik 
2805d528f656SJakub Kruzik   PetscFunctionBegin;
2806d528f656SJakub Kruzik   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2807d528f656SJakub Kruzik   if (size == 1) {
2808d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
2809d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
2810d528f656SJakub Kruzik     } else {
2811d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2812d528f656SJakub Kruzik     }
2813d528f656SJakub Kruzik   } else {
2814d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
2815d528f656SJakub Kruzik   }
2816d528f656SJakub Kruzik   PetscFunctionReturn(0);
2817d528f656SJakub Kruzik }
2818d528f656SJakub Kruzik 
2819*6947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
2820*6947451fSStefano Zampini {
2821*6947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2822*6947451fSStefano Zampini   PetscErrorCode ierr;
2823*6947451fSStefano Zampini 
2824*6947451fSStefano Zampini   PetscFunctionBegin;
2825*6947451fSStefano Zampini   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec first");
2826*6947451fSStefano Zampini   if (!a->cvec) {
2827*6947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
2828*6947451fSStefano Zampini   }
2829*6947451fSStefano Zampini   a->vecinuse = col + 1;
2830*6947451fSStefano Zampini   ierr = MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
2831*6947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
2832*6947451fSStefano Zampini   *v   = a->cvec;
2833*6947451fSStefano Zampini   PetscFunctionReturn(0);
2834*6947451fSStefano Zampini }
2835*6947451fSStefano Zampini 
2836*6947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
2837*6947451fSStefano Zampini {
2838*6947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2839*6947451fSStefano Zampini   PetscErrorCode ierr;
2840*6947451fSStefano Zampini 
2841*6947451fSStefano Zampini   PetscFunctionBegin;
2842*6947451fSStefano Zampini   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec first");
2843*6947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
2844*6947451fSStefano Zampini   a->vecinuse = 0;
2845*6947451fSStefano Zampini   ierr = MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
2846*6947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
2847*6947451fSStefano Zampini   *v   = NULL;
2848*6947451fSStefano Zampini   PetscFunctionReturn(0);
2849*6947451fSStefano Zampini }
2850*6947451fSStefano Zampini 
2851*6947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
2852*6947451fSStefano Zampini {
2853*6947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2854*6947451fSStefano Zampini   PetscErrorCode ierr;
2855*6947451fSStefano Zampini 
2856*6947451fSStefano Zampini   PetscFunctionBegin;
2857*6947451fSStefano Zampini   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec first");
2858*6947451fSStefano Zampini   if (!a->cvec) {
2859*6947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
2860*6947451fSStefano Zampini   }
2861*6947451fSStefano Zampini   a->vecinuse = col + 1;
2862*6947451fSStefano Zampini   ierr = MatDenseGetArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
2863*6947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
2864*6947451fSStefano Zampini   ierr = VecLockReadPush(a->cvec);CHKERRQ(ierr);
2865*6947451fSStefano Zampini   *v   = a->cvec;
2866*6947451fSStefano Zampini   PetscFunctionReturn(0);
2867*6947451fSStefano Zampini }
2868*6947451fSStefano Zampini 
2869*6947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
2870*6947451fSStefano Zampini {
2871*6947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2872*6947451fSStefano Zampini   PetscErrorCode ierr;
2873*6947451fSStefano Zampini 
2874*6947451fSStefano Zampini   PetscFunctionBegin;
2875*6947451fSStefano Zampini   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec first");
2876*6947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
2877*6947451fSStefano Zampini   a->vecinuse = 0;
2878*6947451fSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
2879*6947451fSStefano Zampini   ierr = VecLockReadPop(a->cvec);CHKERRQ(ierr);
2880*6947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
2881*6947451fSStefano Zampini   *v   = NULL;
2882*6947451fSStefano Zampini   PetscFunctionReturn(0);
2883*6947451fSStefano Zampini }
2884*6947451fSStefano Zampini 
2885*6947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
2886*6947451fSStefano Zampini {
2887*6947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2888*6947451fSStefano Zampini   PetscErrorCode ierr;
2889*6947451fSStefano Zampini 
2890*6947451fSStefano Zampini   PetscFunctionBegin;
2891*6947451fSStefano Zampini   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec first");
2892*6947451fSStefano Zampini   if (!a->cvec) {
2893*6947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
2894*6947451fSStefano Zampini   }
2895*6947451fSStefano Zampini   a->vecinuse = col + 1;
2896*6947451fSStefano Zampini   ierr = MatDenseGetArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
2897*6947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
2898*6947451fSStefano Zampini   *v   = a->cvec;
2899*6947451fSStefano Zampini   PetscFunctionReturn(0);
2900*6947451fSStefano Zampini }
2901*6947451fSStefano Zampini 
2902*6947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
2903*6947451fSStefano Zampini {
2904*6947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2905*6947451fSStefano Zampini   PetscErrorCode ierr;
2906*6947451fSStefano Zampini 
2907*6947451fSStefano Zampini   PetscFunctionBegin;
2908*6947451fSStefano Zampini   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec first");
2909*6947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
2910*6947451fSStefano Zampini   a->vecinuse = 0;
2911*6947451fSStefano Zampini   ierr = MatDenseRestoreArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
2912*6947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
2913*6947451fSStefano Zampini   *v   = NULL;
2914*6947451fSStefano Zampini   PetscFunctionReturn(0);
2915*6947451fSStefano Zampini }
2916*6947451fSStefano Zampini 
29170bad9183SKris Buschelman /*MC
2918fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
29190bad9183SKris Buschelman 
29200bad9183SKris Buschelman    Options Database Keys:
29210bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
29220bad9183SKris Buschelman 
29230bad9183SKris Buschelman   Level: beginner
29240bad9183SKris Buschelman 
292589665df3SBarry Smith .seealso: MatCreateSeqDense()
292689665df3SBarry Smith 
29270bad9183SKris Buschelman M*/
2928ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
2929273d9f13SBarry Smith {
2930273d9f13SBarry Smith   Mat_SeqDense   *b;
2931dfbe8321SBarry Smith   PetscErrorCode ierr;
29327c334f02SBarry Smith   PetscMPIInt    size;
2933273d9f13SBarry Smith 
2934273d9f13SBarry Smith   PetscFunctionBegin;
2935ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
2936e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
293755659b69SBarry Smith 
2938b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
2939549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
294044cd7ae7SLois Curfman McInnes   B->data = (void*)b;
294118f449edSLois Curfman McInnes 
2942273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
29434e220ebcSLois Curfman McInnes 
294449a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
2945bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
29468572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2947d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
2948d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
29498572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2950715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2951*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayWrite_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2952*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayWrite_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2953bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
29548baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
29558baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
29568baccfbdSHong Zhang #endif
29572bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
29582bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA);CHKERRQ(ierr);
29594222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
29604222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
2961637a0070SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
29624222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaijcusparse_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
29632bf066beSStefano Zampini #endif
2964bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
29654222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
29664222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
2967bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2968bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
29694222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
2970a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqbaij_seqdense_C",MatMatMultSymbolic_SeqBAIJ_SeqDense);CHKERRQ(ierr);
2971a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqbaij_seqdense_C",MatMatMultNumeric_SeqBAIJ_SeqDense);CHKERRQ(ierr);
29724222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
2973c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqsbaij_seqdense_C",MatMatMultSymbolic_SeqSBAIJ_SeqDense);CHKERRQ(ierr);
2974c2916339SPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqsbaij_seqdense_C",MatMatMultNumeric_SeqSBAIJ_SeqDense);CHKERRQ(ierr);
29754099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijperm_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
29764099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijperm_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2977e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijsell_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2978e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijsell_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
297996e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijmkl_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
298096e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijmkl_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
298152c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_nest_seqdense_C",MatMatMultSymbolic_Nest_Dense);CHKERRQ(ierr);
298252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_nest_seqdense_C",MatMatMultNumeric_Nest_Dense);CHKERRQ(ierr);
298396e6d5c4SRichard Tran Mills 
29843bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
29853bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
29864099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
29874099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2988e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2989e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
299096e6d5c4SRichard Tran Mills 
299196e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
299296e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2993af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
2994af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
2995*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVec_C",MatDenseGetColumnVec_SeqDense);CHKERRQ(ierr);
2996*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVec_C",MatDenseRestoreColumnVec_SeqDense);CHKERRQ(ierr);
2997*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecRead_C",MatDenseGetColumnVecRead_SeqDense);CHKERRQ(ierr);
2998*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecRead_C",MatDenseRestoreColumnVecRead_SeqDense);CHKERRQ(ierr);
2999*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecWrite_C",MatDenseGetColumnVecWrite_SeqDense);CHKERRQ(ierr);
3000*6947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecWrite_C",MatDenseRestoreColumnVecWrite_SeqDense);CHKERRQ(ierr);
300117667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
30023a40ed3dSBarry Smith   PetscFunctionReturn(0);
3003289bc588SBarry Smith }
300486aefd0dSHong Zhang 
300586aefd0dSHong Zhang /*@C
3006af53bab2SHong 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.
300786aefd0dSHong Zhang 
300886aefd0dSHong Zhang    Not Collective
300986aefd0dSHong Zhang 
301086aefd0dSHong Zhang    Input Parameter:
301186aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
301286aefd0dSHong Zhang -  col - column index
301386aefd0dSHong Zhang 
301486aefd0dSHong Zhang    Output Parameter:
301586aefd0dSHong Zhang .  vals - pointer to the data
301686aefd0dSHong Zhang 
301786aefd0dSHong Zhang    Level: intermediate
301886aefd0dSHong Zhang 
301986aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
302086aefd0dSHong Zhang @*/
302186aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
302286aefd0dSHong Zhang {
302386aefd0dSHong Zhang   PetscErrorCode ierr;
302486aefd0dSHong Zhang 
302586aefd0dSHong Zhang   PetscFunctionBegin;
302686aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
302786aefd0dSHong Zhang   PetscFunctionReturn(0);
302886aefd0dSHong Zhang }
302986aefd0dSHong Zhang 
303086aefd0dSHong Zhang /*@C
303186aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
303286aefd0dSHong Zhang 
303386aefd0dSHong Zhang    Not Collective
303486aefd0dSHong Zhang 
303586aefd0dSHong Zhang    Input Parameter:
303686aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
303786aefd0dSHong Zhang 
303886aefd0dSHong Zhang    Output Parameter:
303986aefd0dSHong Zhang .  vals - pointer to the data
304086aefd0dSHong Zhang 
304186aefd0dSHong Zhang    Level: intermediate
304286aefd0dSHong Zhang 
304386aefd0dSHong Zhang .seealso: MatDenseGetColumn()
304486aefd0dSHong Zhang @*/
304586aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
304686aefd0dSHong Zhang {
304786aefd0dSHong Zhang   PetscErrorCode ierr;
304886aefd0dSHong Zhang 
304986aefd0dSHong Zhang   PetscFunctionBegin;
305086aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
305186aefd0dSHong Zhang   PetscFunctionReturn(0);
305286aefd0dSHong Zhang }
3053*6947451fSStefano Zampini 
3054*6947451fSStefano Zampini /*@C
3055*6947451fSStefano Zampini    MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec.
3056*6947451fSStefano Zampini 
3057*6947451fSStefano Zampini    Collective
3058*6947451fSStefano Zampini 
3059*6947451fSStefano Zampini    Input Parameter:
3060*6947451fSStefano Zampini +  mat - the Mat object
3061*6947451fSStefano Zampini -  col - the column index
3062*6947451fSStefano Zampini 
3063*6947451fSStefano Zampini    Output Parameter:
3064*6947451fSStefano Zampini .  v - the vector
3065*6947451fSStefano Zampini 
3066*6947451fSStefano Zampini    Notes:
3067*6947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed.
3068*6947451fSStefano Zampini      Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access.
3069*6947451fSStefano Zampini 
3070*6947451fSStefano Zampini    Level: intermediate
3071*6947451fSStefano Zampini 
3072*6947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
3073*6947451fSStefano Zampini @*/
3074*6947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec(Mat A,PetscInt col,Vec *v)
3075*6947451fSStefano Zampini {
3076*6947451fSStefano Zampini   PetscErrorCode ierr;
3077*6947451fSStefano Zampini 
3078*6947451fSStefano Zampini   PetscFunctionBegin;
3079*6947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3080*6947451fSStefano Zampini   PetscValidType(A,1);
3081*6947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3082*6947451fSStefano Zampini   PetscValidPointer(v,3);
3083*6947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3084*6947451fSStefano 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);
3085*6947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
3086*6947451fSStefano Zampini   PetscFunctionReturn(0);
3087*6947451fSStefano Zampini }
3088*6947451fSStefano Zampini 
3089*6947451fSStefano Zampini /*@C
3090*6947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
3091*6947451fSStefano Zampini 
3092*6947451fSStefano Zampini    Collective
3093*6947451fSStefano Zampini 
3094*6947451fSStefano Zampini    Input Parameter:
3095*6947451fSStefano Zampini +  mat - the Mat object
3096*6947451fSStefano Zampini .  col - the column index
3097*6947451fSStefano Zampini -  v - the Vec object
3098*6947451fSStefano Zampini 
3099*6947451fSStefano Zampini    Level: intermediate
3100*6947451fSStefano Zampini 
3101*6947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
3102*6947451fSStefano Zampini @*/
3103*6947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec *v)
3104*6947451fSStefano Zampini {
3105*6947451fSStefano Zampini   PetscErrorCode ierr;
3106*6947451fSStefano Zampini 
3107*6947451fSStefano Zampini   PetscFunctionBegin;
3108*6947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3109*6947451fSStefano Zampini   PetscValidType(A,1);
3110*6947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3111*6947451fSStefano Zampini   PetscValidPointer(v,3);
3112*6947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3113*6947451fSStefano 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);
3114*6947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
3115*6947451fSStefano Zampini   PetscFunctionReturn(0);
3116*6947451fSStefano Zampini }
3117*6947451fSStefano Zampini 
3118*6947451fSStefano Zampini /*@C
3119*6947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
3120*6947451fSStefano Zampini 
3121*6947451fSStefano Zampini    Collective
3122*6947451fSStefano Zampini 
3123*6947451fSStefano Zampini    Input Parameter:
3124*6947451fSStefano Zampini +  mat - the Mat object
3125*6947451fSStefano Zampini -  col - the column index
3126*6947451fSStefano Zampini 
3127*6947451fSStefano Zampini    Output Parameter:
3128*6947451fSStefano Zampini .  v - the vector
3129*6947451fSStefano Zampini 
3130*6947451fSStefano Zampini    Notes:
3131*6947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
3132*6947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
3133*6947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
3134*6947451fSStefano Zampini 
3135*6947451fSStefano Zampini    Level: intermediate
3136*6947451fSStefano Zampini 
3137*6947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
3138*6947451fSStefano Zampini @*/
3139*6947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec *v)
3140*6947451fSStefano Zampini {
3141*6947451fSStefano Zampini   PetscErrorCode ierr;
3142*6947451fSStefano Zampini 
3143*6947451fSStefano Zampini   PetscFunctionBegin;
3144*6947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3145*6947451fSStefano Zampini   PetscValidType(A,1);
3146*6947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3147*6947451fSStefano Zampini   PetscValidPointer(v,3);
3148*6947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3149*6947451fSStefano 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);
3150*6947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
3151*6947451fSStefano Zampini   PetscFunctionReturn(0);
3152*6947451fSStefano Zampini }
3153*6947451fSStefano Zampini 
3154*6947451fSStefano Zampini /*@C
3155*6947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
3156*6947451fSStefano Zampini 
3157*6947451fSStefano Zampini    Collective
3158*6947451fSStefano Zampini 
3159*6947451fSStefano Zampini    Input Parameter:
3160*6947451fSStefano Zampini +  mat - the Mat object
3161*6947451fSStefano Zampini .  col - the column index
3162*6947451fSStefano Zampini -  v - the Vec object
3163*6947451fSStefano Zampini 
3164*6947451fSStefano Zampini    Level: intermediate
3165*6947451fSStefano Zampini 
3166*6947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecWrite()
3167*6947451fSStefano Zampini @*/
3168*6947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec *v)
3169*6947451fSStefano Zampini {
3170*6947451fSStefano Zampini   PetscErrorCode ierr;
3171*6947451fSStefano Zampini 
3172*6947451fSStefano Zampini   PetscFunctionBegin;
3173*6947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3174*6947451fSStefano Zampini   PetscValidType(A,1);
3175*6947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3176*6947451fSStefano Zampini   PetscValidPointer(v,3);
3177*6947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3178*6947451fSStefano 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);
3179*6947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
3180*6947451fSStefano Zampini   PetscFunctionReturn(0);
3181*6947451fSStefano Zampini }
3182*6947451fSStefano Zampini 
3183*6947451fSStefano Zampini /*@C
3184*6947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
3185*6947451fSStefano Zampini 
3186*6947451fSStefano Zampini    Collective
3187*6947451fSStefano Zampini 
3188*6947451fSStefano Zampini    Input Parameter:
3189*6947451fSStefano Zampini +  mat - the Mat object
3190*6947451fSStefano Zampini -  col - the column index
3191*6947451fSStefano Zampini 
3192*6947451fSStefano Zampini    Output Parameter:
3193*6947451fSStefano Zampini .  v - the vector
3194*6947451fSStefano Zampini 
3195*6947451fSStefano Zampini    Notes:
3196*6947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
3197*6947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
3198*6947451fSStefano Zampini 
3199*6947451fSStefano Zampini    Level: intermediate
3200*6947451fSStefano Zampini 
3201*6947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
3202*6947451fSStefano Zampini @*/
3203*6947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec *v)
3204*6947451fSStefano Zampini {
3205*6947451fSStefano Zampini   PetscErrorCode ierr;
3206*6947451fSStefano Zampini 
3207*6947451fSStefano Zampini   PetscFunctionBegin;
3208*6947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3209*6947451fSStefano Zampini   PetscValidType(A,1);
3210*6947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3211*6947451fSStefano Zampini   PetscValidPointer(v,3);
3212*6947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3213*6947451fSStefano 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);
3214*6947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
3215*6947451fSStefano Zampini   PetscFunctionReturn(0);
3216*6947451fSStefano Zampini }
3217*6947451fSStefano Zampini 
3218*6947451fSStefano Zampini /*@C
3219*6947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
3220*6947451fSStefano Zampini 
3221*6947451fSStefano Zampini    Collective
3222*6947451fSStefano Zampini 
3223*6947451fSStefano Zampini    Input Parameter:
3224*6947451fSStefano Zampini +  mat - the Mat object
3225*6947451fSStefano Zampini .  col - the column index
3226*6947451fSStefano Zampini -  v - the Vec object
3227*6947451fSStefano Zampini 
3228*6947451fSStefano Zampini    Level: intermediate
3229*6947451fSStefano Zampini 
3230*6947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead()
3231*6947451fSStefano Zampini @*/
3232*6947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec *v)
3233*6947451fSStefano Zampini {
3234*6947451fSStefano Zampini   PetscErrorCode ierr;
3235*6947451fSStefano Zampini 
3236*6947451fSStefano Zampini   PetscFunctionBegin;
3237*6947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3238*6947451fSStefano Zampini   PetscValidType(A,1);
3239*6947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3240*6947451fSStefano Zampini   PetscValidPointer(v,3);
3241*6947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3242*6947451fSStefano 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);
3243*6947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
3244*6947451fSStefano Zampini   PetscFunctionReturn(0);
3245*6947451fSStefano Zampini }
3246