xref: /petsc/src/mat/impls/dense/seq/dense.c (revision c70f7ee4f34f80df7a43232bb06cf10c6ca57fb7)
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 #if defined(PETSC_MISSING_LAPACK_POTRF)
418c178816SStefano Zampini   PetscFunctionBegin;
428c178816SStefano Zampini   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF - Lapack routine is unavailable.");
438c178816SStefano Zampini #else
448c178816SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
458c178816SStefano Zampini   PetscErrorCode ierr;
468c178816SStefano Zampini   PetscBLASInt   info,n;
478c178816SStefano Zampini 
488c178816SStefano Zampini   PetscFunctionBegin;
498c178816SStefano Zampini   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
508c178816SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
518c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
528c178816SStefano Zampini     if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
538c178816SStefano Zampini     if (!mat->fwork) {
548c178816SStefano Zampini       mat->lfwork = n;
558c178816SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
568c178816SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
578c178816SStefano Zampini     }
5800121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
598c178816SStefano Zampini     PetscStackCallBLAS("LAPACKgetri",LAPACKgetri_(&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
6000121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
61ca15aa20SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
628c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
638c178816SStefano Zampini     if (A->spd) {
6400121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
658c178816SStefano Zampini       PetscStackCallBLAS("LAPACKpotri",LAPACKpotri_("L",&n,mat->v,&mat->lda,&info));
6600121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
678c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
688c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
698c178816SStefano Zampini     } else if (A->hermitian) {
708c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
718c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
7200121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
738c178816SStefano Zampini       PetscStackCallBLAS("LAPACKhetri",LAPACKhetri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
7400121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
758c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
768c178816SStefano Zampini #endif
778c178816SStefano Zampini     } else { /* symmetric case */
788c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
798c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
8000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
818c178816SStefano Zampini       PetscStackCallBLAS("LAPACKsytri",LAPACKsytri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
8200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
838c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_FALSE);CHKERRQ(ierr);
848c178816SStefano Zampini     }
858c178816SStefano Zampini     if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad Inversion: zero pivot in row %D",(PetscInt)info-1);
86ca15aa20SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
878c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
888c178816SStefano Zampini #endif
898c178816SStefano Zampini 
908c178816SStefano Zampini   A->ops->solve             = NULL;
918c178816SStefano Zampini   A->ops->matsolve          = NULL;
928c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
938c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
948c178816SStefano Zampini   A->ops->solveadd          = NULL;
958c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
968c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
978c178816SStefano Zampini   ierr                      = PetscFree(A->solvertype);CHKERRQ(ierr);
988c178816SStefano Zampini   PetscFunctionReturn(0);
998c178816SStefano Zampini }
1008c178816SStefano Zampini 
1013f49a652SStefano Zampini PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
1023f49a652SStefano Zampini {
1033f49a652SStefano Zampini   PetscErrorCode    ierr;
1043f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1053f49a652SStefano Zampini   PetscInt          m  = l->lda, n = A->cmap->n,r = A->rmap->n, i,j;
106ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
1073f49a652SStefano Zampini   const PetscScalar *xx;
1083f49a652SStefano Zampini 
1093f49a652SStefano Zampini   PetscFunctionBegin;
1103f49a652SStefano Zampini #if defined(PETSC_USE_DEBUG)
1113f49a652SStefano Zampini   for (i=0; i<N; i++) {
1123f49a652SStefano Zampini     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1133f49a652SStefano 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);
1143f49a652SStefano 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);
1153f49a652SStefano Zampini   }
1163f49a652SStefano Zampini #endif
117ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1183f49a652SStefano Zampini 
1193f49a652SStefano Zampini   /* fix right hand side if needed */
1203f49a652SStefano Zampini   if (x && b) {
1216c4d906cSStefano Zampini     Vec xt;
1226c4d906cSStefano Zampini 
1236c4d906cSStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1246c4d906cSStefano Zampini     ierr = VecDuplicate(x,&xt);CHKERRQ(ierr);
1256c4d906cSStefano Zampini     ierr = VecCopy(x,xt);CHKERRQ(ierr);
1266c4d906cSStefano Zampini     ierr = VecScale(xt,-1.0);CHKERRQ(ierr);
1276c4d906cSStefano Zampini     ierr = MatMultAdd(A,xt,b,b);CHKERRQ(ierr);
1286c4d906cSStefano Zampini     ierr = VecDestroy(&xt);CHKERRQ(ierr);
1293f49a652SStefano Zampini     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1303f49a652SStefano Zampini     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
1313f49a652SStefano Zampini     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
1323f49a652SStefano Zampini     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1333f49a652SStefano Zampini     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
1343f49a652SStefano Zampini   }
1353f49a652SStefano Zampini 
136ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1373f49a652SStefano Zampini   for (i=0; i<N; i++) {
138ca15aa20SStefano Zampini     slot = v + rows[i]*m;
139580bdb30SBarry Smith     ierr = PetscArrayzero(slot,r);CHKERRQ(ierr);
1403f49a652SStefano Zampini   }
1413f49a652SStefano Zampini   for (i=0; i<N; i++) {
142ca15aa20SStefano Zampini     slot = v + rows[i];
1433f49a652SStefano Zampini     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
1443f49a652SStefano Zampini   }
1453f49a652SStefano Zampini   if (diag != 0.0) {
1463f49a652SStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1473f49a652SStefano Zampini     for (i=0; i<N; i++) {
148ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1493f49a652SStefano Zampini       *slot = diag;
1503f49a652SStefano Zampini     }
1513f49a652SStefano Zampini   }
152ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
1533f49a652SStefano Zampini   PetscFunctionReturn(0);
1543f49a652SStefano Zampini }
1553f49a652SStefano Zampini 
156abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C)
157abc3b08eSStefano Zampini {
158abc3b08eSStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)(C->data);
159abc3b08eSStefano Zampini   PetscErrorCode ierr;
160abc3b08eSStefano Zampini 
161abc3b08eSStefano Zampini   PetscFunctionBegin;
162ca15aa20SStefano Zampini   if (c->ptapwork) {
163ca15aa20SStefano Zampini     ierr = (*C->ops->matmultnumeric)(A,P,c->ptapwork);CHKERRQ(ierr);
164ca15aa20SStefano Zampini     ierr = (*C->ops->transposematmultnumeric)(P,c->ptapwork,C);CHKERRQ(ierr);
165ca15aa20SStefano Zampini   } else { /* first time went trough the basic. Should we add better dispatching for subclasses? */
166ca15aa20SStefano Zampini     ierr = MatPtAP_Basic(A,P,MAT_REUSE_MATRIX,PETSC_DEFAULT,&C);CHKERRQ(ierr);
167ca15aa20SStefano Zampini   }
168abc3b08eSStefano Zampini   PetscFunctionReturn(0);
169abc3b08eSStefano Zampini }
170abc3b08eSStefano Zampini 
171abc3b08eSStefano Zampini PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat *C)
172abc3b08eSStefano Zampini {
173abc3b08eSStefano Zampini   Mat_SeqDense   *c;
174ca15aa20SStefano Zampini   PetscBool      flg;
175abc3b08eSStefano Zampini   PetscErrorCode ierr;
176abc3b08eSStefano Zampini 
177abc3b08eSStefano Zampini   PetscFunctionBegin;
178ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)P,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
179ca15aa20SStefano Zampini   ierr = MatCreate(PetscObjectComm((PetscObject)A),C);CHKERRQ(ierr);
180ca15aa20SStefano Zampini   ierr = MatSetSizes(*C,P->cmap->n,P->cmap->n,P->cmap->N,P->cmap->N);CHKERRQ(ierr);
181ca15aa20SStefano Zampini   ierr = MatSetType(*C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
182ca15aa20SStefano Zampini   ierr = MatSeqDenseSetPreallocation(*C,NULL);CHKERRQ(ierr);
183abc3b08eSStefano Zampini   c    = (Mat_SeqDense*)((*C)->data);
184ca15aa20SStefano Zampini   ierr = MatCreate(PetscObjectComm((PetscObject)A),&c->ptapwork);CHKERRQ(ierr);
185ca15aa20SStefano Zampini   ierr = MatSetSizes(c->ptapwork,A->rmap->n,P->cmap->n,A->rmap->N,P->cmap->N);CHKERRQ(ierr);
186ca15aa20SStefano Zampini   ierr = MatSetType(c->ptapwork,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
187ca15aa20SStefano Zampini   ierr = MatSeqDenseSetPreallocation(c->ptapwork,NULL);CHKERRQ(ierr);
188abc3b08eSStefano Zampini   PetscFunctionReturn(0);
189abc3b08eSStefano Zampini }
190abc3b08eSStefano Zampini 
191150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatPtAP_SeqDense_SeqDense(Mat A,Mat P,MatReuse reuse,PetscReal fill,Mat *C)
192abc3b08eSStefano Zampini {
193abc3b08eSStefano Zampini   PetscErrorCode ierr;
194abc3b08eSStefano Zampini 
195abc3b08eSStefano Zampini   PetscFunctionBegin;
196abc3b08eSStefano Zampini   if (reuse == MAT_INITIAL_MATRIX) {
197abc3b08eSStefano Zampini     ierr = MatPtAPSymbolic_SeqDense_SeqDense(A,P,fill,C);CHKERRQ(ierr);
198abc3b08eSStefano Zampini   }
199abc3b08eSStefano Zampini   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
200abc3b08eSStefano Zampini   ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
201abc3b08eSStefano Zampini   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
202abc3b08eSStefano Zampini   PetscFunctionReturn(0);
203abc3b08eSStefano Zampini }
204abc3b08eSStefano Zampini 
205cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
206b49cda9fSStefano Zampini {
207a13144ffSStefano Zampini   Mat            B = NULL;
208b49cda9fSStefano Zampini   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
209b49cda9fSStefano Zampini   Mat_SeqDense   *b;
210b49cda9fSStefano Zampini   PetscErrorCode ierr;
211b49cda9fSStefano Zampini   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i;
212b49cda9fSStefano Zampini   MatScalar      *av=a->a;
213a13144ffSStefano Zampini   PetscBool      isseqdense;
214b49cda9fSStefano Zampini 
215b49cda9fSStefano Zampini   PetscFunctionBegin;
216a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
217a13144ffSStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense);CHKERRQ(ierr);
218a32993e3SJed Brown     if (!isseqdense) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type_name);
219a13144ffSStefano Zampini   }
220a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
221b49cda9fSStefano Zampini     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
222b49cda9fSStefano Zampini     ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
223b49cda9fSStefano Zampini     ierr = MatSetType(B,MATSEQDENSE);CHKERRQ(ierr);
224b49cda9fSStefano Zampini     ierr = MatSeqDenseSetPreallocation(B,NULL);CHKERRQ(ierr);
225b49cda9fSStefano Zampini     b    = (Mat_SeqDense*)(B->data);
226a13144ffSStefano Zampini   } else {
227a13144ffSStefano Zampini     b    = (Mat_SeqDense*)((*newmat)->data);
228580bdb30SBarry Smith     ierr = PetscArrayzero(b->v,m*n);CHKERRQ(ierr);
229a13144ffSStefano Zampini   }
230b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
231b49cda9fSStefano Zampini     PetscInt j;
232b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
233b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
234b49cda9fSStefano Zampini       aj++;
235b49cda9fSStefano Zampini       av++;
236b49cda9fSStefano Zampini     }
237b49cda9fSStefano Zampini     ai++;
238b49cda9fSStefano Zampini   }
239b49cda9fSStefano Zampini 
240511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
241a13144ffSStefano Zampini     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
242a13144ffSStefano Zampini     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24328be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
244b49cda9fSStefano Zampini   } else {
245a13144ffSStefano Zampini     if (B) *newmat = B;
246a13144ffSStefano Zampini     ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
247a13144ffSStefano Zampini     ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
248b49cda9fSStefano Zampini   }
249b49cda9fSStefano Zampini   PetscFunctionReturn(0);
250b49cda9fSStefano Zampini }
251b49cda9fSStefano Zampini 
252cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
2536a63e612SBarry Smith {
2546a63e612SBarry Smith   Mat            B;
2556a63e612SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2566a63e612SBarry Smith   PetscErrorCode ierr;
2579399e1b8SMatthew G. Knepley   PetscInt       i, j;
2589399e1b8SMatthew G. Knepley   PetscInt       *rows, *nnz;
2599399e1b8SMatthew G. Knepley   MatScalar      *aa = a->v, *vals;
2606a63e612SBarry Smith 
2616a63e612SBarry Smith   PetscFunctionBegin;
262ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
2636a63e612SBarry Smith   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
2646a63e612SBarry Smith   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
2659399e1b8SMatthew G. Knepley   ierr = PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals);CHKERRQ(ierr);
2669399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2679399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) ++nnz[i];
2686a63e612SBarry Smith     aa += a->lda;
2696a63e612SBarry Smith   }
2709399e1b8SMatthew G. Knepley   ierr = MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz);CHKERRQ(ierr);
2719399e1b8SMatthew G. Knepley   aa = a->v;
2729399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2739399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2749399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) {rows[numRows] = i; vals[numRows++] = aa[i];}
2759399e1b8SMatthew G. Knepley     ierr = MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr);
2769399e1b8SMatthew G. Knepley     aa  += a->lda;
2779399e1b8SMatthew G. Knepley   }
2789399e1b8SMatthew G. Knepley   ierr = PetscFree3(rows,nnz,vals);CHKERRQ(ierr);
2796a63e612SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2806a63e612SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2816a63e612SBarry Smith 
282511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
28328be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
2846a63e612SBarry Smith   } else {
2856a63e612SBarry Smith     *newmat = B;
2866a63e612SBarry Smith   }
2876a63e612SBarry Smith   PetscFunctionReturn(0);
2886a63e612SBarry Smith }
2896a63e612SBarry Smith 
290ca15aa20SStefano Zampini PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
2911987afe7SBarry Smith {
2921987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
293ca15aa20SStefano Zampini   const PetscScalar *xv;
294ca15aa20SStefano Zampini   PetscScalar       *yv;
2950805154bSBarry Smith   PetscBLASInt      N,m,ldax,lday,one = 1;
296efee365bSSatish Balay   PetscErrorCode    ierr;
2973a40ed3dSBarry Smith 
2983a40ed3dSBarry Smith   PetscFunctionBegin;
299ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(X,&xv);CHKERRQ(ierr);
300ca15aa20SStefano Zampini   ierr = MatDenseGetArray(Y,&yv);CHKERRQ(ierr);
301c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n*X->cmap->n,&N);CHKERRQ(ierr);
302c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n,&m);CHKERRQ(ierr);
303c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->lda,&ldax);CHKERRQ(ierr);
304c5df96a5SBarry Smith   ierr = PetscBLASIntCast(y->lda,&lday);CHKERRQ(ierr);
305a5ce6ee0Svictorle   if (ldax>m || lday>m) {
306ca15aa20SStefano Zampini     PetscInt j;
307ca15aa20SStefano Zampini 
308d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
309ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&alpha,xv+j*ldax,&one,yv+j*lday,&one));
310a5ce6ee0Svictorle     }
311a5ce6ee0Svictorle   } else {
312ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&alpha,xv,&one,yv,&one));
313a5ce6ee0Svictorle   }
314ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(X,&xv);CHKERRQ(ierr);
315ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(Y,&yv);CHKERRQ(ierr);
3160450473dSBarry Smith   ierr = PetscLogFlops(PetscMax(2*N-1,0));CHKERRQ(ierr);
3173a40ed3dSBarry Smith   PetscFunctionReturn(0);
3181987afe7SBarry Smith }
3191987afe7SBarry Smith 
320e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
321289bc588SBarry Smith {
322ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n*A->cmap->n;
3233a40ed3dSBarry Smith 
3243a40ed3dSBarry Smith   PetscFunctionBegin;
3254e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
326ca15aa20SStefano Zampini   info->nz_allocated      = N;
327ca15aa20SStefano Zampini   info->nz_used           = N;
328ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
329ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
3304e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3317adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3324e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3334e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3344e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3353a40ed3dSBarry Smith   PetscFunctionReturn(0);
336289bc588SBarry Smith }
337289bc588SBarry Smith 
338e0877f53SBarry Smith static PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
33980cd9d93SLois Curfman McInnes {
340273d9f13SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
341ca15aa20SStefano Zampini   PetscScalar    *v;
342efee365bSSatish Balay   PetscErrorCode ierr;
343c5df96a5SBarry Smith   PetscBLASInt   one = 1,j,nz,lda;
34480cd9d93SLois Curfman McInnes 
3453a40ed3dSBarry Smith   PetscFunctionBegin;
346ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
347c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->lda,&lda);CHKERRQ(ierr);
348d0f46423SBarry Smith   if (lda>A->rmap->n) {
349c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n,&nz);CHKERRQ(ierr);
350d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
351ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v+j*lda,&one));
352a5ce6ee0Svictorle     }
353a5ce6ee0Svictorle   } else {
354c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz);CHKERRQ(ierr);
355ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v,&one));
356a5ce6ee0Svictorle   }
357efee365bSSatish Balay   ierr = PetscLogFlops(nz);CHKERRQ(ierr);
358ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
3593a40ed3dSBarry Smith   PetscFunctionReturn(0);
36080cd9d93SLois Curfman McInnes }
36180cd9d93SLois Curfman McInnes 
362e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3631cbb95d3SBarry Smith {
3641cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
365ca15aa20SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
366ca15aa20SStefano Zampini   const PetscScalar *v;
367ca15aa20SStefano Zampini   PetscErrorCode    ierr;
3681cbb95d3SBarry Smith 
3691cbb95d3SBarry Smith   PetscFunctionBegin;
3701cbb95d3SBarry Smith   *fl = PETSC_FALSE;
371d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
372ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
3731cbb95d3SBarry Smith   for (i=0; i<m; i++) {
374ca15aa20SStefano Zampini     for (j=i; j<m; j++) {
3751cbb95d3SBarry Smith       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) PetscFunctionReturn(0);
3761cbb95d3SBarry Smith     }
3771cbb95d3SBarry Smith   }
378ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
3791cbb95d3SBarry Smith   *fl  = PETSC_TRUE;
3801cbb95d3SBarry Smith   PetscFunctionReturn(0);
3811cbb95d3SBarry Smith }
3821cbb95d3SBarry Smith 
383ca15aa20SStefano Zampini PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
384b24902e0SBarry Smith {
385ca15aa20SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
386b24902e0SBarry Smith   PetscErrorCode ierr;
387b24902e0SBarry Smith   PetscInt       lda = (PetscInt)mat->lda,j,m;
388b24902e0SBarry Smith 
389b24902e0SBarry Smith   PetscFunctionBegin;
390aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr);
391aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr);
3920298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr);
393b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
394ca15aa20SStefano Zampini     const PetscScalar *av;
395ca15aa20SStefano Zampini     PetscScalar       *v;
396ca15aa20SStefano Zampini 
397ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
398ca15aa20SStefano Zampini     ierr = MatDenseGetArray(newi,&v);CHKERRQ(ierr);
399d0f46423SBarry Smith     if (lda>A->rmap->n) {
400d0f46423SBarry Smith       m = A->rmap->n;
401d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
402ca15aa20SStefano Zampini         ierr = PetscArraycpy(v+j*m,av+j*lda,m);CHKERRQ(ierr);
403b24902e0SBarry Smith       }
404b24902e0SBarry Smith     } else {
405ca15aa20SStefano Zampini       ierr = PetscArraycpy(v,av,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
406b24902e0SBarry Smith     }
407ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(newi,&v);CHKERRQ(ierr);
408ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
409b24902e0SBarry Smith   }
410b24902e0SBarry Smith   PetscFunctionReturn(0);
411b24902e0SBarry Smith }
412b24902e0SBarry Smith 
413ca15aa20SStefano Zampini PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
41402cad45dSBarry Smith {
4156849ba73SBarry Smith   PetscErrorCode ierr;
41602cad45dSBarry Smith 
4173a40ed3dSBarry Smith   PetscFunctionBegin;
418ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr);
419d0f46423SBarry Smith   ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4205c9eb25fSBarry Smith   ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
421719d5645SBarry Smith   ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr);
422b24902e0SBarry Smith   PetscFunctionReturn(0);
423b24902e0SBarry Smith }
424b24902e0SBarry Smith 
425e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
426289bc588SBarry Smith {
4274482741eSBarry Smith   MatFactorInfo  info;
428a093e273SMatthew Knepley   PetscErrorCode ierr;
4293a40ed3dSBarry Smith 
4303a40ed3dSBarry Smith   PetscFunctionBegin;
431c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
432ca15aa20SStefano Zampini   ierr = (*fact->ops->lufactor)(fact,0,0,&info);CHKERRQ(ierr);
4333a40ed3dSBarry Smith   PetscFunctionReturn(0);
434289bc588SBarry Smith }
4356ee01492SSatish Balay 
436e0877f53SBarry Smith static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy)
437289bc588SBarry Smith {
438c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
4396849ba73SBarry Smith   PetscErrorCode    ierr;
440f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
441f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
442c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
44367e560aaSBarry Smith 
4443a40ed3dSBarry Smith   PetscFunctionBegin;
445c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
446f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4471ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
448580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
449d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_LU) {
450ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
451e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
452ae7cfcebSSatish Balay #else
45300121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4548b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
45500121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
456e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
457ae7cfcebSSatish Balay #endif
458d5f3da31SBarry Smith   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
459ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
460e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
461ae7cfcebSSatish Balay #else
462a49dc2a2SStefano Zampini     if (A->spd) {
46300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4648b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
46500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
466e32f2f54SBarry Smith       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
467a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
468a49dc2a2SStefano Zampini     } else if (A->hermitian) {
46900121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
470a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
47100121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
472a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
473a49dc2a2SStefano Zampini #endif
474a49dc2a2SStefano Zampini     } else { /* symmetric case */
47500121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
476a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
47700121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
478a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
479a49dc2a2SStefano Zampini     }
480ae7cfcebSSatish Balay #endif
4812205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
482f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4831ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
484dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
4853a40ed3dSBarry Smith   PetscFunctionReturn(0);
486289bc588SBarry Smith }
4876ee01492SSatish Balay 
488e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X)
48985e2c93fSHong Zhang {
49085e2c93fSHong Zhang   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
49185e2c93fSHong Zhang   PetscErrorCode    ierr;
4921683a169SBarry Smith   const PetscScalar *b;
4931683a169SBarry Smith   PetscScalar       *x;
494efb80c78SLisandro Dalcin   PetscInt          n;
495783b601eSJed Brown   PetscBLASInt      nrhs,info,m;
49685e2c93fSHong Zhang 
49785e2c93fSHong Zhang   PetscFunctionBegin;
498c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
4990298fd71SBarry Smith   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
500c5df96a5SBarry Smith   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
5011683a169SBarry Smith   ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
5028c778c55SBarry Smith   ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr);
50385e2c93fSHong Zhang 
504580bdb30SBarry Smith   ierr = PetscArraycpy(x,b,m*nrhs);CHKERRQ(ierr);
50585e2c93fSHong Zhang 
50685e2c93fSHong Zhang   if (A->factortype == MAT_FACTOR_LU) {
50785e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_GETRS)
50885e2c93fSHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
50985e2c93fSHong Zhang #else
51000121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5118b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
51200121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
51385e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
51485e2c93fSHong Zhang #endif
51585e2c93fSHong Zhang   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
51685e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_POTRS)
51785e2c93fSHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
51885e2c93fSHong Zhang #else
519a49dc2a2SStefano Zampini     if (A->spd) {
52000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5218b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
52200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
52385e2c93fSHong Zhang       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
524a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
525a49dc2a2SStefano Zampini     } else if (A->hermitian) {
52600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
527a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
52800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
529a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
530a49dc2a2SStefano Zampini #endif
531a49dc2a2SStefano Zampini     } else { /* symmetric case */
53200121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
533a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
53400121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
535a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
536a49dc2a2SStefano Zampini     }
53785e2c93fSHong Zhang #endif
5382205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
53985e2c93fSHong Zhang 
5401683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
5418c778c55SBarry Smith   ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr);
54285e2c93fSHong Zhang   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
54385e2c93fSHong Zhang   PetscFunctionReturn(0);
54485e2c93fSHong Zhang }
54585e2c93fSHong Zhang 
54600121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
54700121966SStefano Zampini 
548e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
549da3a660dSBarry Smith {
550c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
551dfbe8321SBarry Smith   PetscErrorCode    ierr;
552f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
553f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
554c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
55567e560aaSBarry Smith 
5563a40ed3dSBarry Smith   PetscFunctionBegin;
557c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
558f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5591ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
560580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
5618208b9aeSStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
562ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
563e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
564ae7cfcebSSatish Balay #else
56500121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5668b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
56700121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
568e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve");
569ae7cfcebSSatish Balay #endif
5708208b9aeSStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
571ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
572e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
573ae7cfcebSSatish Balay #else
574a49dc2a2SStefano Zampini     if (A->spd) {
57500121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
57600121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
57700121966SStefano Zampini #endif
57800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5798b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
58000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
58100121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
58200121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
58300121966SStefano Zampini #endif
584a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
585a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
586a49dc2a2SStefano Zampini     } else if (A->hermitian) {
58700121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
58800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
58900121966SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
59000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
59100121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
592ae7cfcebSSatish Balay #endif
593a49dc2a2SStefano Zampini     } else { /* symmetric case */
59400121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
595a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
59600121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
597a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
598da3a660dSBarry Smith     }
599a49dc2a2SStefano Zampini #endif
600a49dc2a2SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
601f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
6021ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
603dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
6043a40ed3dSBarry Smith   PetscFunctionReturn(0);
605da3a660dSBarry Smith }
6066ee01492SSatish Balay 
607db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
608db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
609db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
610ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
611db4efbfdSBarry Smith {
612db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_GETRF)
613db4efbfdSBarry Smith   PetscFunctionBegin;
614e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRF - Lapack routine is unavailable.");
615db4efbfdSBarry Smith #else
616db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
617db4efbfdSBarry Smith   PetscErrorCode ierr;
618db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
619db4efbfdSBarry Smith 
620db4efbfdSBarry Smith   PetscFunctionBegin;
621c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
622c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
623db4efbfdSBarry Smith   if (!mat->pivots) {
6248208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
6253bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
626db4efbfdSBarry Smith   }
627db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
6288e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6298b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
6308e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
6318e57ea43SSatish Balay 
632e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
633e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
6348208b9aeSStefano Zampini 
635db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6368208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
637db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
638d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
639db4efbfdSBarry Smith 
640f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
641f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
642f6224b95SHong Zhang 
643dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
644db4efbfdSBarry Smith #endif
645db4efbfdSBarry Smith   PetscFunctionReturn(0);
646db4efbfdSBarry Smith }
647db4efbfdSBarry Smith 
648a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
649ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
650db4efbfdSBarry Smith {
651db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_POTRF)
652db4efbfdSBarry Smith   PetscFunctionBegin;
653e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF - Lapack routine is unavailable.");
654db4efbfdSBarry Smith #else
655db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
656db4efbfdSBarry Smith   PetscErrorCode ierr;
657c5df96a5SBarry Smith   PetscBLASInt   info,n;
658db4efbfdSBarry Smith 
659db4efbfdSBarry Smith   PetscFunctionBegin;
660c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
661db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
662a49dc2a2SStefano Zampini   if (A->spd) {
66300121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6648b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
66500121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
666a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
667a49dc2a2SStefano Zampini   } else if (A->hermitian) {
668a49dc2a2SStefano Zampini     if (!mat->pivots) {
669a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
670a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
671a49dc2a2SStefano Zampini     }
672a49dc2a2SStefano Zampini     if (!mat->fwork) {
673a49dc2a2SStefano Zampini       PetscScalar dummy;
674a49dc2a2SStefano Zampini 
675a49dc2a2SStefano Zampini       mat->lfwork = -1;
67600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
677a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
67800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
679a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
680a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
681a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
682a49dc2a2SStefano Zampini     }
68300121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
684a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
68500121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
686a49dc2a2SStefano Zampini #endif
687a49dc2a2SStefano Zampini   } else { /* symmetric case */
688a49dc2a2SStefano Zampini     if (!mat->pivots) {
689a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
690a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
691a49dc2a2SStefano Zampini     }
692a49dc2a2SStefano Zampini     if (!mat->fwork) {
693a49dc2a2SStefano Zampini       PetscScalar dummy;
694a49dc2a2SStefano Zampini 
695a49dc2a2SStefano Zampini       mat->lfwork = -1;
69600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
697a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
69800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
699a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
700a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
701a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
702a49dc2a2SStefano Zampini     }
70300121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
704a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
70500121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
706a49dc2a2SStefano Zampini   }
707e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
7088208b9aeSStefano Zampini 
709db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
7108208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
711db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
712d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
7132205254eSKarl Rupp 
714f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
715f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
716f6224b95SHong Zhang 
717eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
718db4efbfdSBarry Smith #endif
719db4efbfdSBarry Smith   PetscFunctionReturn(0);
720db4efbfdSBarry Smith }
721db4efbfdSBarry Smith 
722db4efbfdSBarry Smith 
7230481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
724db4efbfdSBarry Smith {
725db4efbfdSBarry Smith   PetscErrorCode ierr;
726db4efbfdSBarry Smith   MatFactorInfo  info;
727db4efbfdSBarry Smith 
728db4efbfdSBarry Smith   PetscFunctionBegin;
729db4efbfdSBarry Smith   info.fill = 1.0;
7302205254eSKarl Rupp 
731c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
732ca15aa20SStefano Zampini   ierr = (*fact->ops->choleskyfactor)(fact,0,&info);CHKERRQ(ierr);
733db4efbfdSBarry Smith   PetscFunctionReturn(0);
734db4efbfdSBarry Smith }
735db4efbfdSBarry Smith 
736ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
737db4efbfdSBarry Smith {
738db4efbfdSBarry Smith   PetscFunctionBegin;
739c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
7401bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
741719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
742bd443b22SStefano Zampini   fact->ops->solve                 = MatSolve_SeqDense;
743bd443b22SStefano Zampini   fact->ops->matsolve              = MatMatSolve_SeqDense;
744bd443b22SStefano Zampini   fact->ops->solvetranspose        = MatSolveTranspose_SeqDense;
745db4efbfdSBarry Smith   PetscFunctionReturn(0);
746db4efbfdSBarry Smith }
747db4efbfdSBarry Smith 
748ca15aa20SStefano Zampini PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
749db4efbfdSBarry Smith {
750db4efbfdSBarry Smith   PetscFunctionBegin;
751b66fe19dSMatthew G Knepley   fact->preallocated           = PETSC_TRUE;
752c3ef05f6SHong Zhang   fact->assembled              = PETSC_TRUE;
753719d5645SBarry Smith   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
754bd443b22SStefano Zampini   fact->ops->solve             = MatSolve_SeqDense;
755bd443b22SStefano Zampini   fact->ops->matsolve          = MatMatSolve_SeqDense;
756bd443b22SStefano Zampini   fact->ops->solvetranspose    = MatSolveTranspose_SeqDense;
757db4efbfdSBarry Smith   PetscFunctionReturn(0);
758db4efbfdSBarry Smith }
759db4efbfdSBarry Smith 
760ca15aa20SStefano Zampini /* uses LAPACK */
761cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
762db4efbfdSBarry Smith {
763db4efbfdSBarry Smith   PetscErrorCode ierr;
764db4efbfdSBarry Smith 
765db4efbfdSBarry Smith   PetscFunctionBegin;
766ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
767db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
768ca15aa20SStefano Zampini   ierr = MatSetType(*fact,MATDENSE);CHKERRQ(ierr);
769db4efbfdSBarry Smith   if (ftype == MAT_FACTOR_LU) {
770db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
771db4efbfdSBarry Smith   } else {
772db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
773db4efbfdSBarry Smith   }
774d5f3da31SBarry Smith   (*fact)->factortype = ftype;
77500c67f3bSHong Zhang 
77600c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
77700c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
778db4efbfdSBarry Smith   PetscFunctionReturn(0);
779db4efbfdSBarry Smith }
780db4efbfdSBarry Smith 
781289bc588SBarry Smith /* ------------------------------------------------------------------*/
782e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
783289bc588SBarry Smith {
784c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
785d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
786d9ca1df4SBarry Smith   const PetscScalar *b;
787dfbe8321SBarry Smith   PetscErrorCode    ierr;
788d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
789c5df96a5SBarry Smith   PetscBLASInt      o = 1,bm;
790289bc588SBarry Smith 
7913a40ed3dSBarry Smith   PetscFunctionBegin;
792ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
793*c70f7ee4SJunchao Zhang   if (A->offloadmask == PETSC_OFFLOAD_GPU) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
794ca15aa20SStefano Zampini #endif
795422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
796c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
797289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
7983bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
7992dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
800289bc588SBarry Smith   }
8011ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
802d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
803b965ef7fSBarry Smith   its  = its*lits;
804e32f2f54SBarry 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);
805289bc588SBarry Smith   while (its--) {
806fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
807289bc588SBarry Smith       for (i=0; i<m; i++) {
8083bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
80955a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
810289bc588SBarry Smith       }
811289bc588SBarry Smith     }
812fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
813289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
8143bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
81555a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
816289bc588SBarry Smith       }
817289bc588SBarry Smith     }
818289bc588SBarry Smith   }
819d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
8201ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
8213a40ed3dSBarry Smith   PetscFunctionReturn(0);
822289bc588SBarry Smith }
823289bc588SBarry Smith 
824289bc588SBarry Smith /* -----------------------------------------------------------------*/
825ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
826289bc588SBarry Smith {
827c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
828d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
829d9ca1df4SBarry Smith   PetscScalar       *y;
830dfbe8321SBarry Smith   PetscErrorCode    ierr;
8310805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
832ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
8333a40ed3dSBarry Smith 
8343a40ed3dSBarry Smith   PetscFunctionBegin;
835c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
836c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
837d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8382bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
8395ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8405ac36cfcSBarry Smith     PetscBLASInt i;
8415ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
8425ac36cfcSBarry Smith   } else {
8438b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
8445ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
8455ac36cfcSBarry Smith   }
846d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8472bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
8483a40ed3dSBarry Smith   PetscFunctionReturn(0);
849289bc588SBarry Smith }
850800995b7SMatthew Knepley 
851ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
852289bc588SBarry Smith {
853c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
854d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
855dfbe8321SBarry Smith   PetscErrorCode    ierr;
8560805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
857d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
8583a40ed3dSBarry Smith 
8593a40ed3dSBarry Smith   PetscFunctionBegin;
860c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
861c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
862d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8632bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
8645ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8655ac36cfcSBarry Smith     PetscBLASInt i;
8665ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
8675ac36cfcSBarry Smith   } else {
8688b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
8695ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
8705ac36cfcSBarry Smith   }
871d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8722bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
8733a40ed3dSBarry Smith   PetscFunctionReturn(0);
874289bc588SBarry Smith }
8756ee01492SSatish Balay 
876ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
877289bc588SBarry Smith {
878c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
879d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
880d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
881dfbe8321SBarry Smith   PetscErrorCode    ierr;
8820805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
8833a40ed3dSBarry Smith 
8843a40ed3dSBarry Smith   PetscFunctionBegin;
885c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
886c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
887d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
888600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
889d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8901ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8918b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
892d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8931ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
894dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8953a40ed3dSBarry Smith   PetscFunctionReturn(0);
896289bc588SBarry Smith }
8976ee01492SSatish Balay 
898ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
899289bc588SBarry Smith {
900c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
901d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
902d9ca1df4SBarry Smith   PetscScalar       *y;
903dfbe8321SBarry Smith   PetscErrorCode    ierr;
9040805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
90587828ca2SBarry Smith   PetscScalar       _DOne=1.0;
9063a40ed3dSBarry Smith 
9073a40ed3dSBarry Smith   PetscFunctionBegin;
908c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
909c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
910d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
911600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
912d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
9131ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9148b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
915d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
9161ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
917dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
9183a40ed3dSBarry Smith   PetscFunctionReturn(0);
919289bc588SBarry Smith }
920289bc588SBarry Smith 
921289bc588SBarry Smith /* -----------------------------------------------------------------*/
922e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
923289bc588SBarry Smith {
924c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
9256849ba73SBarry Smith   PetscErrorCode ierr;
92613f74950SBarry Smith   PetscInt       i;
92767e560aaSBarry Smith 
9283a40ed3dSBarry Smith   PetscFunctionBegin;
929d0f46423SBarry Smith   *ncols = A->cmap->n;
930289bc588SBarry Smith   if (cols) {
931854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
932d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
933289bc588SBarry Smith   }
934289bc588SBarry Smith   if (vals) {
935ca15aa20SStefano Zampini     const PetscScalar *v;
936ca15aa20SStefano Zampini 
937ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
938854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
939ca15aa20SStefano Zampini     v   += row;
940d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
941ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
942289bc588SBarry Smith   }
9433a40ed3dSBarry Smith   PetscFunctionReturn(0);
944289bc588SBarry Smith }
9456ee01492SSatish Balay 
946e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
947289bc588SBarry Smith {
948dfbe8321SBarry Smith   PetscErrorCode ierr;
9496e111a19SKarl Rupp 
950606d414cSSatish Balay   PetscFunctionBegin;
951606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
952606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
9533a40ed3dSBarry Smith   PetscFunctionReturn(0);
954289bc588SBarry Smith }
955289bc588SBarry Smith /* ----------------------------------------------------------------*/
956e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
957289bc588SBarry Smith {
958c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
959ca15aa20SStefano Zampini   PetscScalar      *av;
96013f74950SBarry Smith   PetscInt         i,j,idx=0;
961ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
962*c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
963ca15aa20SStefano Zampini #endif
964ca15aa20SStefano Zampini   PetscErrorCode   ierr;
965d6dfbf8fSBarry Smith 
9663a40ed3dSBarry Smith   PetscFunctionBegin;
967ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&av);CHKERRQ(ierr);
968289bc588SBarry Smith   if (!mat->roworiented) {
969dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
970289bc588SBarry Smith       for (j=0; j<n; j++) {
971cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
9722515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
973e32f2f54SBarry Smith         if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
97458804f6dSBarry Smith #endif
975289bc588SBarry Smith         for (i=0; i<m; i++) {
976cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
9772515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
978e32f2f54SBarry Smith           if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
97958804f6dSBarry Smith #endif
980ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
981289bc588SBarry Smith         }
982289bc588SBarry Smith       }
9833a40ed3dSBarry Smith     } else {
984289bc588SBarry Smith       for (j=0; j<n; j++) {
985cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
9862515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
987e32f2f54SBarry Smith         if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
98858804f6dSBarry Smith #endif
989289bc588SBarry Smith         for (i=0; i<m; i++) {
990cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
9912515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
992e32f2f54SBarry Smith           if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
99358804f6dSBarry Smith #endif
994ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
995289bc588SBarry Smith         }
996289bc588SBarry Smith       }
997289bc588SBarry Smith     }
9983a40ed3dSBarry Smith   } else {
999dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1000e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
1001cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
10022515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1003e32f2f54SBarry Smith         if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
100458804f6dSBarry Smith #endif
1005e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
1006cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
10072515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1008e32f2f54SBarry Smith           if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
100958804f6dSBarry Smith #endif
1010ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1011e8d4e0b9SBarry Smith         }
1012e8d4e0b9SBarry Smith       }
10133a40ed3dSBarry Smith     } else {
1014289bc588SBarry Smith       for (i=0; i<m; i++) {
1015cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
10162515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1017e32f2f54SBarry Smith         if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
101858804f6dSBarry Smith #endif
1019289bc588SBarry Smith         for (j=0; j<n; j++) {
1020cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
10212515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1022e32f2f54SBarry Smith           if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
102358804f6dSBarry Smith #endif
1024ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1025289bc588SBarry Smith         }
1026289bc588SBarry Smith       }
1027289bc588SBarry Smith     }
1028e8d4e0b9SBarry Smith   }
1029ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
1030ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1031*c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
1032*c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1033ca15aa20SStefano Zampini #endif
1034ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&av);CHKERRQ(ierr);
1035ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1036*c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1037ca15aa20SStefano Zampini #endif
10383a40ed3dSBarry Smith   PetscFunctionReturn(0);
1039289bc588SBarry Smith }
1040e8d4e0b9SBarry Smith 
1041e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1042ae80bb75SLois Curfman McInnes {
1043ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1044ca15aa20SStefano Zampini   const PetscScalar *vv;
104513f74950SBarry Smith   PetscInt          i,j;
1046ca15aa20SStefano Zampini   PetscErrorCode    ierr;
1047ae80bb75SLois Curfman McInnes 
10483a40ed3dSBarry Smith   PetscFunctionBegin;
1049ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1050ae80bb75SLois Curfman McInnes   /* row-oriented output */
1051ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
105297e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1053e32f2f54SBarry 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);
1054ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
10556f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1056e32f2f54SBarry 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);
1057ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1058ae80bb75SLois Curfman McInnes     }
1059ae80bb75SLois Curfman McInnes   }
1060ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
10613a40ed3dSBarry Smith   PetscFunctionReturn(0);
1062ae80bb75SLois Curfman McInnes }
1063ae80bb75SLois Curfman McInnes 
1064289bc588SBarry Smith /* -----------------------------------------------------------------*/
1065289bc588SBarry Smith 
1066eb91f321SVaclav Hapla static PetscErrorCode MatLoad_SeqDense_Binary(Mat newmat,PetscViewer viewer)
1067aabbc4fbSShri Abhyankar {
1068aabbc4fbSShri Abhyankar   Mat_SeqDense   *a;
1069aabbc4fbSShri Abhyankar   PetscErrorCode ierr;
1070aabbc4fbSShri Abhyankar   PetscInt       *scols,i,j,nz,header[4];
1071aabbc4fbSShri Abhyankar   int            fd;
1072aabbc4fbSShri Abhyankar   PetscMPIInt    size;
1073aabbc4fbSShri Abhyankar   PetscInt       *rowlengths = 0,M,N,*cols,grows,gcols;
1074aabbc4fbSShri Abhyankar   PetscScalar    *vals,*svals,*v,*w;
1075ce94432eSBarry Smith   MPI_Comm       comm;
1076aabbc4fbSShri Abhyankar 
1077aabbc4fbSShri Abhyankar   PetscFunctionBegin;
1078ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
1079aabbc4fbSShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1080aabbc4fbSShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"view must have one processor");
1081aabbc4fbSShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
10829860990eSLisandro Dalcin   ierr = PetscBinaryRead(fd,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
1083aabbc4fbSShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not matrix object");
1084aabbc4fbSShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
1085aabbc4fbSShri Abhyankar 
1086aabbc4fbSShri Abhyankar   /* set global size if not set already*/
1087aabbc4fbSShri Abhyankar   if (newmat->rmap->n < 0 && newmat->rmap->N < 0 && newmat->cmap->n < 0 && newmat->cmap->N < 0) {
1088aabbc4fbSShri Abhyankar     ierr = MatSetSizes(newmat,M,N,M,N);CHKERRQ(ierr);
1089aabbc4fbSShri Abhyankar   } else {
1090aabbc4fbSShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
1091aabbc4fbSShri Abhyankar     ierr = MatGetSize(newmat,&grows,&gcols);CHKERRQ(ierr);
1092aabbc4fbSShri Abhyankar     if (M != grows ||  N != gcols) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different length (%d, %d) than the input matrix (%d, %d)",M,N,grows,gcols);
1093aabbc4fbSShri Abhyankar   }
1094e6324fbbSBarry Smith   a = (Mat_SeqDense*)newmat->data;
1095e6324fbbSBarry Smith   if (!a->user_alloc) {
10960298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1097e6324fbbSBarry Smith   }
1098aabbc4fbSShri Abhyankar 
1099aabbc4fbSShri Abhyankar   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense */
1100aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
1101aabbc4fbSShri Abhyankar     v = a->v;
1102aabbc4fbSShri Abhyankar     /* Allocate some temp space to read in the values and then flip them
1103aabbc4fbSShri Abhyankar        from row major to column major */
1104854ce69bSBarry Smith     ierr = PetscMalloc1(M*N > 0 ? M*N : 1,&w);CHKERRQ(ierr);
1105aabbc4fbSShri Abhyankar     /* read in nonzero values */
11069860990eSLisandro Dalcin     ierr = PetscBinaryRead(fd,w,M*N,NULL,PETSC_SCALAR);CHKERRQ(ierr);
1107aabbc4fbSShri Abhyankar     /* now flip the values and store them in the matrix*/
1108aabbc4fbSShri Abhyankar     for (j=0; j<N; j++) {
1109aabbc4fbSShri Abhyankar       for (i=0; i<M; i++) {
1110aabbc4fbSShri Abhyankar         *v++ =w[i*N+j];
1111aabbc4fbSShri Abhyankar       }
1112aabbc4fbSShri Abhyankar     }
1113aabbc4fbSShri Abhyankar     ierr = PetscFree(w);CHKERRQ(ierr);
1114aabbc4fbSShri Abhyankar   } else {
1115aabbc4fbSShri Abhyankar     /* read row lengths */
1116854ce69bSBarry Smith     ierr = PetscMalloc1(M+1,&rowlengths);CHKERRQ(ierr);
11179860990eSLisandro Dalcin     ierr = PetscBinaryRead(fd,rowlengths,M,NULL,PETSC_INT);CHKERRQ(ierr);
1118aabbc4fbSShri Abhyankar 
1119aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
1120aabbc4fbSShri Abhyankar     v = a->v;
1121aabbc4fbSShri Abhyankar 
1122aabbc4fbSShri Abhyankar     /* read column indices and nonzeros */
1123854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&scols);CHKERRQ(ierr);
1124aabbc4fbSShri Abhyankar     cols = scols;
11259860990eSLisandro Dalcin     ierr = PetscBinaryRead(fd,cols,nz,NULL,PETSC_INT);CHKERRQ(ierr);
1126854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&svals);CHKERRQ(ierr);
1127aabbc4fbSShri Abhyankar     vals = svals;
11289860990eSLisandro Dalcin     ierr = PetscBinaryRead(fd,vals,nz,NULL,PETSC_SCALAR);CHKERRQ(ierr);
1129aabbc4fbSShri Abhyankar 
1130aabbc4fbSShri Abhyankar     /* insert into matrix */
1131aabbc4fbSShri Abhyankar     for (i=0; i<M; i++) {
1132aabbc4fbSShri Abhyankar       for (j=0; j<rowlengths[i]; j++) v[i+M*scols[j]] = svals[j];
1133aabbc4fbSShri Abhyankar       svals += rowlengths[i]; scols += rowlengths[i];
1134aabbc4fbSShri Abhyankar     }
1135aabbc4fbSShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1136aabbc4fbSShri Abhyankar     ierr = PetscFree(cols);CHKERRQ(ierr);
1137aabbc4fbSShri Abhyankar     ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1138aabbc4fbSShri Abhyankar   }
1139aabbc4fbSShri Abhyankar   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1140aabbc4fbSShri Abhyankar   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1141aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1142aabbc4fbSShri Abhyankar }
1143aabbc4fbSShri Abhyankar 
1144eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1145eb91f321SVaclav Hapla {
1146eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1147eb91f321SVaclav Hapla   PetscErrorCode ierr;
1148eb91f321SVaclav Hapla 
1149eb91f321SVaclav Hapla   PetscFunctionBegin;
1150eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1151eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1152eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
1153eb91f321SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1154eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1155eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1156eb91f321SVaclav Hapla   if (isbinary) {
1157eb91f321SVaclav Hapla     ierr = MatLoad_SeqDense_Binary(newMat,viewer);CHKERRQ(ierr);
1158eb91f321SVaclav Hapla   } else if (ishdf5) {
1159eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
1160eb91f321SVaclav Hapla     ierr = MatLoad_Dense_HDF5(newMat,viewer);CHKERRQ(ierr);
1161eb91f321SVaclav Hapla #else
1162eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1163eb91f321SVaclav Hapla #endif
1164eb91f321SVaclav Hapla   } else {
1165eb91f321SVaclav 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);
1166eb91f321SVaclav Hapla   }
1167eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1168eb91f321SVaclav Hapla }
1169eb91f321SVaclav Hapla 
11706849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1171289bc588SBarry Smith {
1172932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1173dfbe8321SBarry Smith   PetscErrorCode    ierr;
117413f74950SBarry Smith   PetscInt          i,j;
11752dcb1b2aSMatthew Knepley   const char        *name;
1176ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1177f3ef73ceSBarry Smith   PetscViewerFormat format;
11785f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1179ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
11805f481a85SSatish Balay #endif
1181932b0c3eSLois Curfman McInnes 
11823a40ed3dSBarry Smith   PetscFunctionBegin;
1183ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1184b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1185456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
11863a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1187fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1188d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1189d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1190ca15aa20SStefano Zampini       v    = av + i;
119177431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1192d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1193aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1194329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
119557622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1196329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
119757622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
11986831982aSBarry Smith         }
119980cd9d93SLois Curfman McInnes #else
12006831982aSBarry Smith         if (*v) {
120157622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
12026831982aSBarry Smith         }
120380cd9d93SLois Curfman McInnes #endif
12041b807ce4Svictorle         v += a->lda;
120580cd9d93SLois Curfman McInnes       }
1206b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
120780cd9d93SLois Curfman McInnes     }
1208d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
12093a40ed3dSBarry Smith   } else {
1210d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1211aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
121247989497SBarry Smith     /* determine if matrix has all real values */
1213ca15aa20SStefano Zampini     v = av;
1214d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1215ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
121647989497SBarry Smith     }
121747989497SBarry Smith #endif
1218fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
12193a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1220d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1221d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1222fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1223ffac6cdbSBarry Smith     }
1224ffac6cdbSBarry Smith 
1225d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1226ca15aa20SStefano Zampini       v = av + i;
1227d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1228aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
122947989497SBarry Smith         if (allreal) {
1230c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
123147989497SBarry Smith         } else {
1232c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
123347989497SBarry Smith         }
1234289bc588SBarry Smith #else
1235c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1236289bc588SBarry Smith #endif
12371b807ce4Svictorle         v += a->lda;
1238289bc588SBarry Smith       }
1239b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1240289bc588SBarry Smith     }
1241fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1242b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1243ffac6cdbSBarry Smith     }
1244d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1245da3a660dSBarry Smith   }
1246ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1247b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
12483a40ed3dSBarry Smith   PetscFunctionReturn(0);
1249289bc588SBarry Smith }
1250289bc588SBarry Smith 
12516849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_Binary(Mat A,PetscViewer viewer)
1252932b0c3eSLois Curfman McInnes {
1253932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
12546849ba73SBarry Smith   PetscErrorCode    ierr;
125513f74950SBarry Smith   int               fd;
1256d0f46423SBarry Smith   PetscInt          ict,j,n = A->cmap->n,m = A->rmap->n,i,*col_lens,nz = m*n;
1257ca15aa20SStefano Zampini   PetscScalar       *av,*v,*anonz,*vals;
1258f4403165SShri Abhyankar   PetscViewerFormat format;
1259932b0c3eSLois Curfman McInnes 
12603a40ed3dSBarry Smith   PetscFunctionBegin;
1261b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
1262ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1263f4403165SShri Abhyankar   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1264f4403165SShri Abhyankar   if (format == PETSC_VIEWER_NATIVE) {
1265f4403165SShri Abhyankar     /* store the matrix as a dense matrix */
1266785e854fSJed Brown     ierr = PetscMalloc1(4,&col_lens);CHKERRQ(ierr);
12672205254eSKarl Rupp 
1268f4403165SShri Abhyankar     col_lens[0] = MAT_FILE_CLASSID;
1269f4403165SShri Abhyankar     col_lens[1] = m;
1270f4403165SShri Abhyankar     col_lens[2] = n;
1271f4403165SShri Abhyankar     col_lens[3] = MATRIX_BINARY_FORMAT_DENSE;
12722205254eSKarl Rupp 
1273f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,col_lens,4,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1274f4403165SShri Abhyankar     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1275f4403165SShri Abhyankar 
1276f4403165SShri Abhyankar     /* write out matrix, by rows */
1277854ce69bSBarry Smith     ierr = PetscMalloc1(m*n+1,&vals);CHKERRQ(ierr);
1278ca15aa20SStefano Zampini     v    = av;
1279f4403165SShri Abhyankar     for (j=0; j<n; j++) {
1280f4403165SShri Abhyankar       for (i=0; i<m; i++) {
1281f4403165SShri Abhyankar         vals[j + i*n] = *v++;
1282f4403165SShri Abhyankar       }
1283f4403165SShri Abhyankar     }
1284f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,vals,n*m,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1285f4403165SShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1286f4403165SShri Abhyankar   } else {
1287854ce69bSBarry Smith     ierr = PetscMalloc1(4+nz,&col_lens);CHKERRQ(ierr);
12882205254eSKarl Rupp 
12890700a824SBarry Smith     col_lens[0] = MAT_FILE_CLASSID;
1290932b0c3eSLois Curfman McInnes     col_lens[1] = m;
1291932b0c3eSLois Curfman McInnes     col_lens[2] = n;
1292932b0c3eSLois Curfman McInnes     col_lens[3] = nz;
1293932b0c3eSLois Curfman McInnes 
1294932b0c3eSLois Curfman McInnes     /* store lengths of each row and write (including header) to file */
1295932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) col_lens[4+i] = n;
12966f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,4+m,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1297932b0c3eSLois Curfman McInnes 
1298932b0c3eSLois Curfman McInnes     /* Possibly should write in smaller increments, not whole matrix at once? */
1299932b0c3eSLois Curfman McInnes     /* store column indices (zero start index) */
1300932b0c3eSLois Curfman McInnes     ict = 0;
1301932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1302932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) col_lens[ict++] = j;
1303932b0c3eSLois Curfman McInnes     }
13046f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
1305606d414cSSatish Balay     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1306932b0c3eSLois Curfman McInnes 
1307932b0c3eSLois Curfman McInnes     /* store nonzero values */
1308854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&anonz);CHKERRQ(ierr);
1309932b0c3eSLois Curfman McInnes     ict  = 0;
1310932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1311ca15aa20SStefano Zampini       v = av + i;
1312932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) {
13131b807ce4Svictorle         anonz[ict++] = *v; v += a->lda;
1314932b0c3eSLois Curfman McInnes       }
1315932b0c3eSLois Curfman McInnes     }
13166f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,anonz,nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1317606d414cSSatish Balay     ierr = PetscFree(anonz);CHKERRQ(ierr);
1318f4403165SShri Abhyankar   }
1319ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
13203a40ed3dSBarry Smith   PetscFunctionReturn(0);
1321932b0c3eSLois Curfman McInnes }
1322932b0c3eSLois Curfman McInnes 
13239804daf3SBarry Smith #include <petscdraw.h>
1324e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1325f1af5d2fSBarry Smith {
1326f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
13276849ba73SBarry Smith   PetscErrorCode    ierr;
1328383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1329383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1330ca15aa20SStefano Zampini   const PetscScalar *v;
1331b0a32e0cSBarry Smith   PetscViewer       viewer;
1332b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1333f3ef73ceSBarry Smith   PetscViewerFormat format;
1334f1af5d2fSBarry Smith 
1335f1af5d2fSBarry Smith   PetscFunctionBegin;
1336f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1337b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1338b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1339f1af5d2fSBarry Smith 
1340f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1341ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1342fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1343383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1344f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1345f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1346383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1347f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1348f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1349f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1350ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1351ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1352ca15aa20SStefano Zampini         else continue;
1353b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1354f1af5d2fSBarry Smith       }
1355f1af5d2fSBarry Smith     }
1356383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1357f1af5d2fSBarry Smith   } else {
1358f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1359f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1360b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1361b05fc000SLisandro Dalcin     PetscDraw popup;
1362b05fc000SLisandro Dalcin 
1363f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1364f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1365f1af5d2fSBarry Smith     }
1366383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1367b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
136845f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1369383922c3SLisandro Dalcin 
1370383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1371f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1372f1af5d2fSBarry Smith       x_l = j;
1373f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1374f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1375f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1376f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1377b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1378b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1379f1af5d2fSBarry Smith       }
1380f1af5d2fSBarry Smith     }
1381383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1382f1af5d2fSBarry Smith   }
1383ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1384f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1385f1af5d2fSBarry Smith }
1386f1af5d2fSBarry Smith 
1387e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1388f1af5d2fSBarry Smith {
1389b0a32e0cSBarry Smith   PetscDraw      draw;
1390ace3abfcSBarry Smith   PetscBool      isnull;
1391329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1392dfbe8321SBarry Smith   PetscErrorCode ierr;
1393f1af5d2fSBarry Smith 
1394f1af5d2fSBarry Smith   PetscFunctionBegin;
1395b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1396b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1397abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1398f1af5d2fSBarry Smith 
1399d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1400f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1401b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1402832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1403b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
14040298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1405832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1406f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1407f1af5d2fSBarry Smith }
1408f1af5d2fSBarry Smith 
1409dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1410932b0c3eSLois Curfman McInnes {
1411dfbe8321SBarry Smith   PetscErrorCode ierr;
1412ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1413932b0c3eSLois Curfman McInnes 
14143a40ed3dSBarry Smith   PetscFunctionBegin;
1415251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1416251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1417251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
14180f5bd95cSBarry Smith 
1419c45a1595SBarry Smith   if (iascii) {
1420c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
14210f5bd95cSBarry Smith   } else if (isbinary) {
14223a40ed3dSBarry Smith     ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr);
1423f1af5d2fSBarry Smith   } else if (isdraw) {
1424f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1425932b0c3eSLois Curfman McInnes   }
14263a40ed3dSBarry Smith   PetscFunctionReturn(0);
1427932b0c3eSLois Curfman McInnes }
1428289bc588SBarry Smith 
1429d3042a70SBarry Smith static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar array[])
1430d3042a70SBarry Smith {
1431d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1432d3042a70SBarry Smith 
1433d3042a70SBarry Smith   PetscFunctionBegin;
1434d3042a70SBarry Smith   a->unplacedarray       = a->v;
1435d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1436d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1437ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1438*c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1439ca15aa20SStefano Zampini #endif
1440d3042a70SBarry Smith   PetscFunctionReturn(0);
1441d3042a70SBarry Smith }
1442d3042a70SBarry Smith 
1443d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1444d3042a70SBarry Smith {
1445d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1446d3042a70SBarry Smith 
1447d3042a70SBarry Smith   PetscFunctionBegin;
1448d3042a70SBarry Smith   a->v             = a->unplacedarray;
1449d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1450d3042a70SBarry Smith   a->unplacedarray = NULL;
1451ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1452*c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1453ca15aa20SStefano Zampini #endif
1454d3042a70SBarry Smith   PetscFunctionReturn(0);
1455d3042a70SBarry Smith }
1456d3042a70SBarry Smith 
1457ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1458289bc588SBarry Smith {
1459ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1460dfbe8321SBarry Smith   PetscErrorCode ierr;
146190f02eecSBarry Smith 
14623a40ed3dSBarry Smith   PetscFunctionBegin;
1463aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1464d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1465a5a9c739SBarry Smith #endif
146605b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1467a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1468abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
14696857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1470bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1471dbd8c25aSHong Zhang 
1472dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
147349a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1474bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
1475d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1476d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
1477bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
14788baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
14798baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
14808baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
14818baccfbdSHong Zhang #endif
14822bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
14832bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL);CHKERRQ(ierr);
1484a4af7ca8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaijcusparse_seqdense_C",NULL);CHKERRQ(ierr);
1485a4af7ca8SStefano Zampini #endif
1486a4af7ca8SStefano Zampini #if defined(PETSC_HAVE_VIENNACL)
1487a4af7ca8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaijviennacl_seqdense_C",NULL);CHKERRQ(ierr);
14882bf066beSStefano Zampini #endif
1489bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
1490bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1491bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1492bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1493a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1494a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1495a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1496abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatPtAP_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14973bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14983bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14993bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
150086aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
150186aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
15023a40ed3dSBarry Smith   PetscFunctionReturn(0);
1503289bc588SBarry Smith }
1504289bc588SBarry Smith 
1505e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1506289bc588SBarry Smith {
1507c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
15086849ba73SBarry Smith   PetscErrorCode ierr;
150913f74950SBarry Smith   PetscInt       k,j,m,n,M;
151087828ca2SBarry Smith   PetscScalar    *v,tmp;
151148b35521SBarry Smith 
15123a40ed3dSBarry Smith   PetscFunctionBegin;
1513ca15aa20SStefano Zampini   m = A->rmap->n; M = mat->lda; n = A->cmap->n;
15142847e3fdSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX && m == n) { /* in place transpose */
1515ca15aa20SStefano Zampini     ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1516d3e5ee88SLois Curfman McInnes     for (j=0; j<m; j++) {
1517289bc588SBarry Smith       for (k=0; k<j; k++) {
15181b807ce4Svictorle         tmp        = v[j + k*M];
15191b807ce4Svictorle         v[j + k*M] = v[k + j*M];
15201b807ce4Svictorle         v[k + j*M] = tmp;
1521289bc588SBarry Smith       }
1522289bc588SBarry Smith     }
1523ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
15243a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1525d3e5ee88SLois Curfman McInnes     Mat          tmat;
1526ec8511deSBarry Smith     Mat_SeqDense *tmatd;
152787828ca2SBarry Smith     PetscScalar  *v2;
1528af36a384SStefano Zampini     PetscInt     M2;
1529ea709b57SSatish Balay 
15302847e3fdSStefano Zampini     if (reuse != MAT_REUSE_MATRIX) {
1531ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1532d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
15337adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
15340298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1535ca15aa20SStefano Zampini     } else tmat = *matout;
1536ca15aa20SStefano Zampini 
1537ca15aa20SStefano Zampini     ierr  = MatDenseGetArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
1538ca15aa20SStefano Zampini     ierr  = MatDenseGetArray(tmat,&v2);CHKERRQ(ierr);
1539ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1540ca15aa20SStefano Zampini     M2    = tmatd->lda;
1541d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1542af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1543d3e5ee88SLois Curfman McInnes     }
1544ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(tmat,&v2);CHKERRQ(ierr);
1545ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
15466d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15476d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15482847e3fdSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) *matout = tmat;
15492847e3fdSStefano Zampini     else {
15502847e3fdSStefano Zampini       ierr = MatHeaderMerge(A,&tmat);CHKERRQ(ierr);
15512847e3fdSStefano Zampini     }
155248b35521SBarry Smith   }
15533a40ed3dSBarry Smith   PetscFunctionReturn(0);
1554289bc588SBarry Smith }
1555289bc588SBarry Smith 
1556e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1557289bc588SBarry Smith {
1558c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1559c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1560ca15aa20SStefano Zampini   PetscInt          i;
1561ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
1562ca15aa20SStefano Zampini   PetscErrorCode    ierr;
15639ea5d5aeSSatish Balay 
15643a40ed3dSBarry Smith   PetscFunctionBegin;
1565d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1566d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1567ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A1,&v1);CHKERRQ(ierr);
1568ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A2,&v2);CHKERRQ(ierr);
1569ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
1570ca15aa20SStefano Zampini     ierr = PetscArraycmp(v1,v2,A1->rmap->n,flg);CHKERRQ(ierr);
1571ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1572ca15aa20SStefano Zampini     v1 += mat1->lda;
1573ca15aa20SStefano Zampini     v2 += mat2->lda;
15741b807ce4Svictorle   }
1575ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A1,&v1);CHKERRQ(ierr);
1576ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A2,&v2);CHKERRQ(ierr);
157777c4ece6SBarry Smith   *flg = PETSC_TRUE;
15783a40ed3dSBarry Smith   PetscFunctionReturn(0);
1579289bc588SBarry Smith }
1580289bc588SBarry Smith 
1581e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1582289bc588SBarry Smith {
1583c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
158413f74950SBarry Smith   PetscInt          i,n,len;
1585ca15aa20SStefano Zampini   PetscScalar       *x;
1586ca15aa20SStefano Zampini   const PetscScalar *vv;
1587ca15aa20SStefano Zampini   PetscErrorCode    ierr;
158844cd7ae7SLois Curfman McInnes 
15893a40ed3dSBarry Smith   PetscFunctionBegin;
15907a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
15911ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1592d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1593ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1594e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
159544cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1596ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1597289bc588SBarry Smith   }
1598ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
15991ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
16003a40ed3dSBarry Smith   PetscFunctionReturn(0);
1601289bc588SBarry Smith }
1602289bc588SBarry Smith 
1603e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1604289bc588SBarry Smith {
1605c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1606f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1607ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1608dfbe8321SBarry Smith   PetscErrorCode    ierr;
1609d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
161055659b69SBarry Smith 
16113a40ed3dSBarry Smith   PetscFunctionBegin;
1612ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&vv);CHKERRQ(ierr);
161328988994SBarry Smith   if (ll) {
16147a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1615f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1616e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1617da3a660dSBarry Smith     for (i=0; i<m; i++) {
1618da3a660dSBarry Smith       x = l[i];
1619ca15aa20SStefano Zampini       v = vv + i;
1620b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1621da3a660dSBarry Smith     }
1622f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1623eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1624da3a660dSBarry Smith   }
162528988994SBarry Smith   if (rr) {
16267a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1627f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1628e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1629da3a660dSBarry Smith     for (i=0; i<n; i++) {
1630da3a660dSBarry Smith       x = r[i];
1631ca15aa20SStefano Zampini       v = vv + i*mat->lda;
16322205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1633da3a660dSBarry Smith     }
1634f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1635eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1636da3a660dSBarry Smith   }
1637ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&vv);CHKERRQ(ierr);
16383a40ed3dSBarry Smith   PetscFunctionReturn(0);
1639289bc588SBarry Smith }
1640289bc588SBarry Smith 
1641ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1642289bc588SBarry Smith {
1643c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1644ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1645329f5518SBarry Smith   PetscReal         sum  = 0.0;
1646d0f46423SBarry Smith   PetscInt          lda  =mat->lda,m=A->rmap->n,i,j;
1647efee365bSSatish Balay   PetscErrorCode    ierr;
164855659b69SBarry Smith 
16493a40ed3dSBarry Smith   PetscFunctionBegin;
1650ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
1651ca15aa20SStefano Zampini   v    = vv;
1652289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1653a5ce6ee0Svictorle     if (lda>m) {
1654d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1655ca15aa20SStefano Zampini         v = vv+j*lda;
1656a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1657a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1658a5ce6ee0Svictorle         }
1659a5ce6ee0Svictorle       }
1660a5ce6ee0Svictorle     } else {
1661570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1662570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1663570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1664570b7f6dSBarry Smith     }
1665570b7f6dSBarry Smith #else
1666d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1667329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1668289bc588SBarry Smith       }
1669a5ce6ee0Svictorle     }
16708f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1671570b7f6dSBarry Smith #endif
1672dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16733a40ed3dSBarry Smith   } else if (type == NORM_1) {
1674064f8208SBarry Smith     *nrm = 0.0;
1675d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1676ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
1677289bc588SBarry Smith       sum = 0.0;
1678d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
167933a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1680289bc588SBarry Smith       }
1681064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1682289bc588SBarry Smith     }
1683eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16843a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1685064f8208SBarry Smith     *nrm = 0.0;
1686d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1687ca15aa20SStefano Zampini       v   = vv + j;
1688289bc588SBarry Smith       sum = 0.0;
1689d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
16901b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1691289bc588SBarry Smith       }
1692064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1693289bc588SBarry Smith     }
1694eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1695e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
1696ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
16973a40ed3dSBarry Smith   PetscFunctionReturn(0);
1698289bc588SBarry Smith }
1699289bc588SBarry Smith 
1700e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1701289bc588SBarry Smith {
1702c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
170363ba0a88SBarry Smith   PetscErrorCode ierr;
170467e560aaSBarry Smith 
17053a40ed3dSBarry Smith   PetscFunctionBegin;
1706b5a2b587SKris Buschelman   switch (op) {
1707b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
17084e0d8c25SBarry Smith     aij->roworiented = flg;
1709b5a2b587SKris Buschelman     break;
1710512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1711b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
17123971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
17134e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
171413fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1715b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1716b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
17170f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
17185021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
1719071fcb05SBarry Smith   case MAT_SORTED_FULL:
17205021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
17215021d80fSJed Brown     break;
17225021d80fSJed Brown   case MAT_SPD:
172377e54ba9SKris Buschelman   case MAT_SYMMETRIC:
172477e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
17259a4540c5SBarry Smith   case MAT_HERMITIAN:
17269a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
17275021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
172877e54ba9SKris Buschelman     break;
1729b5a2b587SKris Buschelman   default:
1730e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
17313a40ed3dSBarry Smith   }
17323a40ed3dSBarry Smith   PetscFunctionReturn(0);
1733289bc588SBarry Smith }
1734289bc588SBarry Smith 
1735e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
17366f0a148fSBarry Smith {
1737ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
17386849ba73SBarry Smith   PetscErrorCode ierr;
1739d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
1740ca15aa20SStefano Zampini   PetscScalar    *v;
17413a40ed3dSBarry Smith 
17423a40ed3dSBarry Smith   PetscFunctionBegin;
1743ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1744a5ce6ee0Svictorle   if (lda>m) {
1745d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1746ca15aa20SStefano Zampini       ierr = PetscArrayzero(v+j*lda,m);CHKERRQ(ierr);
1747a5ce6ee0Svictorle     }
1748a5ce6ee0Svictorle   } else {
1749ca15aa20SStefano Zampini     ierr = PetscArrayzero(v,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
1750a5ce6ee0Svictorle   }
1751ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17523a40ed3dSBarry Smith   PetscFunctionReturn(0);
17536f0a148fSBarry Smith }
17546f0a148fSBarry Smith 
1755e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
17566f0a148fSBarry Smith {
175797b48c8fSBarry Smith   PetscErrorCode    ierr;
1758ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1759b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
1760ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
176197b48c8fSBarry Smith   const PetscScalar *xx;
176255659b69SBarry Smith 
17633a40ed3dSBarry Smith   PetscFunctionBegin;
1764b9679d65SBarry Smith #if defined(PETSC_USE_DEBUG)
1765b9679d65SBarry Smith   for (i=0; i<N; i++) {
1766b9679d65SBarry Smith     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1767b9679d65SBarry 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);
1768b9679d65SBarry Smith   }
1769b9679d65SBarry Smith #endif
1770ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1771b9679d65SBarry Smith 
177297b48c8fSBarry Smith   /* fix right hand side if needed */
177397b48c8fSBarry Smith   if (x && b) {
177497b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
177597b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
17762205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
177797b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
177897b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
177997b48c8fSBarry Smith   }
178097b48c8fSBarry Smith 
1781ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
17826f0a148fSBarry Smith   for (i=0; i<N; i++) {
1783ca15aa20SStefano Zampini     slot = v + rows[i];
1784b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
17856f0a148fSBarry Smith   }
1786f4df32b1SMatthew Knepley   if (diag != 0.0) {
1787b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
17886f0a148fSBarry Smith     for (i=0; i<N; i++) {
1789ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1790f4df32b1SMatthew Knepley       *slot = diag;
17916f0a148fSBarry Smith     }
17926f0a148fSBarry Smith   }
1793ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17943a40ed3dSBarry Smith   PetscFunctionReturn(0);
17956f0a148fSBarry Smith }
1796557bce09SLois Curfman McInnes 
179749a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
179849a6ff4bSBarry Smith {
179949a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
180049a6ff4bSBarry Smith 
180149a6ff4bSBarry Smith   PetscFunctionBegin;
180249a6ff4bSBarry Smith   *lda = mat->lda;
180349a6ff4bSBarry Smith   PetscFunctionReturn(0);
180449a6ff4bSBarry Smith }
180549a6ff4bSBarry Smith 
1806ca15aa20SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar *array[])
180764e87e97SBarry Smith {
1808c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
18093a40ed3dSBarry Smith 
18103a40ed3dSBarry Smith   PetscFunctionBegin;
181164e87e97SBarry Smith   *array = mat->v;
18123a40ed3dSBarry Smith   PetscFunctionReturn(0);
181364e87e97SBarry Smith }
18140754003eSLois Curfman McInnes 
1815ca15aa20SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar *array[])
1816ff14e315SSatish Balay {
18173a40ed3dSBarry Smith   PetscFunctionBegin;
18183a40ed3dSBarry Smith   PetscFunctionReturn(0);
1819ff14e315SSatish Balay }
18200754003eSLois Curfman McInnes 
1821dec5eb66SMatthew G Knepley /*@C
182249a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
182349a6ff4bSBarry Smith 
182449a6ff4bSBarry Smith    Logically Collective on Mat
182549a6ff4bSBarry Smith 
182649a6ff4bSBarry Smith    Input Parameter:
182749a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
182849a6ff4bSBarry Smith 
182949a6ff4bSBarry Smith    Output Parameter:
183049a6ff4bSBarry Smith .   lda - the leading dimension
183149a6ff4bSBarry Smith 
183249a6ff4bSBarry Smith    Level: intermediate
183349a6ff4bSBarry Smith 
183449a6ff4bSBarry Smith .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatSeqDenseSetLDA()
183549a6ff4bSBarry Smith @*/
183649a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
183749a6ff4bSBarry Smith {
183849a6ff4bSBarry Smith   PetscErrorCode ierr;
183949a6ff4bSBarry Smith 
184049a6ff4bSBarry Smith   PetscFunctionBegin;
184149a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
184249a6ff4bSBarry Smith   PetscFunctionReturn(0);
184349a6ff4bSBarry Smith }
184449a6ff4bSBarry Smith 
184549a6ff4bSBarry Smith /*@C
18468c778c55SBarry Smith    MatDenseGetArray - gives access to the array where the data for a SeqDense matrix is stored
184773a71a0fSBarry Smith 
18488572280aSBarry Smith    Logically Collective on Mat
184973a71a0fSBarry Smith 
185073a71a0fSBarry Smith    Input Parameter:
1851579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
185273a71a0fSBarry Smith 
185373a71a0fSBarry Smith    Output Parameter:
185473a71a0fSBarry Smith .   array - pointer to the data
185573a71a0fSBarry Smith 
185673a71a0fSBarry Smith    Level: intermediate
185773a71a0fSBarry Smith 
18588572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
185973a71a0fSBarry Smith @*/
18608c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
186173a71a0fSBarry Smith {
186273a71a0fSBarry Smith   PetscErrorCode ierr;
186373a71a0fSBarry Smith 
186473a71a0fSBarry Smith   PetscFunctionBegin;
18658c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
186673a71a0fSBarry Smith   PetscFunctionReturn(0);
186773a71a0fSBarry Smith }
186873a71a0fSBarry Smith 
1869dec5eb66SMatthew G Knepley /*@C
1870579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
187173a71a0fSBarry Smith 
18728572280aSBarry Smith    Logically Collective on Mat
18738572280aSBarry Smith 
18748572280aSBarry Smith    Input Parameters:
1875a2b725a8SWilliam Gropp +  mat - a MATSEQDENSE or MATMPIDENSE matrix
1876a2b725a8SWilliam Gropp -  array - pointer to the data
18778572280aSBarry Smith 
18788572280aSBarry Smith    Level: intermediate
18798572280aSBarry Smith 
18808572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
18818572280aSBarry Smith @*/
18828572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
18838572280aSBarry Smith {
18848572280aSBarry Smith   PetscErrorCode ierr;
18858572280aSBarry Smith 
18868572280aSBarry Smith   PetscFunctionBegin;
18878572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
18888572280aSBarry Smith   if (array) *array = NULL;
18898572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
18908572280aSBarry Smith   PetscFunctionReturn(0);
18918572280aSBarry Smith }
18928572280aSBarry Smith 
18938572280aSBarry Smith /*@C
18948572280aSBarry Smith    MatDenseGetArrayRead - gives access to the array where the data for a SeqDense matrix is stored
18958572280aSBarry Smith 
18968572280aSBarry Smith    Not Collective
18978572280aSBarry Smith 
18988572280aSBarry Smith    Input Parameter:
18998572280aSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
19008572280aSBarry Smith 
19018572280aSBarry Smith    Output Parameter:
19028572280aSBarry Smith .   array - pointer to the data
19038572280aSBarry Smith 
19048572280aSBarry Smith    Level: intermediate
19058572280aSBarry Smith 
19068572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArray(), MatDenseRestoreArrayRead()
19078572280aSBarry Smith @*/
19088572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
19098572280aSBarry Smith {
19108572280aSBarry Smith   PetscErrorCode ierr;
19118572280aSBarry Smith 
19128572280aSBarry Smith   PetscFunctionBegin;
19138572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
19148572280aSBarry Smith   PetscFunctionReturn(0);
19158572280aSBarry Smith }
19168572280aSBarry Smith 
19178572280aSBarry Smith /*@C
19188572280aSBarry Smith    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
19198572280aSBarry Smith 
192073a71a0fSBarry Smith    Not Collective
192173a71a0fSBarry Smith 
192273a71a0fSBarry Smith    Input Parameters:
1923a2b725a8SWilliam Gropp +  mat - a MATSEQDENSE or MATMPIDENSE matrix
1924a2b725a8SWilliam Gropp -  array - pointer to the data
192573a71a0fSBarry Smith 
192673a71a0fSBarry Smith    Level: intermediate
192773a71a0fSBarry Smith 
19288572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArray()
192973a71a0fSBarry Smith @*/
19308572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
193173a71a0fSBarry Smith {
193273a71a0fSBarry Smith   PetscErrorCode ierr;
193373a71a0fSBarry Smith 
193473a71a0fSBarry Smith   PetscFunctionBegin;
19358572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
19368572280aSBarry Smith   if (array) *array = NULL;
193773a71a0fSBarry Smith   PetscFunctionReturn(0);
193873a71a0fSBarry Smith }
193973a71a0fSBarry Smith 
19407dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
19410754003eSLois Curfman McInnes {
1942c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
19436849ba73SBarry Smith   PetscErrorCode ierr;
1944ca15aa20SStefano Zampini   PetscInt       i,j,nrows,ncols,blda;
19455d0c19d7SBarry Smith   const PetscInt *irow,*icol;
194687828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
19470754003eSLois Curfman McInnes   Mat            newmat;
19480754003eSLois Curfman McInnes 
19493a40ed3dSBarry Smith   PetscFunctionBegin;
195078b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
195178b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1952e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1953e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
19540754003eSLois Curfman McInnes 
1955182d2002SSatish Balay   /* Check submatrixcall */
1956182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
195713f74950SBarry Smith     PetscInt n_cols,n_rows;
1958182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
195921a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
1960f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
1961c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
196221a2c019SBarry Smith     }
1963182d2002SSatish Balay     newmat = *B;
1964182d2002SSatish Balay   } else {
19650754003eSLois Curfman McInnes     /* Create and fill new matrix */
1966ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
1967f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
19687adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
19690298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1970182d2002SSatish Balay   }
1971182d2002SSatish Balay 
1972182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1973ca15aa20SStefano Zampini   ierr = MatDenseGetArray(newmat,&bv);CHKERRQ(ierr);
1974ca15aa20SStefano Zampini   ierr = MatDenseGetLDA(newmat,&blda);CHKERRQ(ierr);
1975182d2002SSatish Balay   for (i=0; i<ncols; i++) {
19766de62eeeSBarry Smith     av = v + mat->lda*icol[i];
1977ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
1978ca15aa20SStefano Zampini     bv += blda;
19790754003eSLois Curfman McInnes   }
1980ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(newmat,&bv);CHKERRQ(ierr);
1981182d2002SSatish Balay 
1982182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
19836d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19846d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19850754003eSLois Curfman McInnes 
19860754003eSLois Curfman McInnes   /* Free work space */
198778b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
198878b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1989182d2002SSatish Balay   *B   = newmat;
19903a40ed3dSBarry Smith   PetscFunctionReturn(0);
19910754003eSLois Curfman McInnes }
19920754003eSLois Curfman McInnes 
19937dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1994905e6a2fSBarry Smith {
19956849ba73SBarry Smith   PetscErrorCode ierr;
199613f74950SBarry Smith   PetscInt       i;
1997905e6a2fSBarry Smith 
19983a40ed3dSBarry Smith   PetscFunctionBegin;
1999905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2000df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
2001905e6a2fSBarry Smith   }
2002905e6a2fSBarry Smith 
2003905e6a2fSBarry Smith   for (i=0; i<n; i++) {
20047dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2005905e6a2fSBarry Smith   }
20063a40ed3dSBarry Smith   PetscFunctionReturn(0);
2007905e6a2fSBarry Smith }
2008905e6a2fSBarry Smith 
2009e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2010c0aa2d19SHong Zhang {
2011c0aa2d19SHong Zhang   PetscFunctionBegin;
2012c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2013c0aa2d19SHong Zhang }
2014c0aa2d19SHong Zhang 
2015e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2016c0aa2d19SHong Zhang {
2017c0aa2d19SHong Zhang   PetscFunctionBegin;
2018c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2019c0aa2d19SHong Zhang }
2020c0aa2d19SHong Zhang 
2021e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
20224b0e389bSBarry Smith {
20234b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
20246849ba73SBarry Smith   PetscErrorCode    ierr;
2025ca15aa20SStefano Zampini   const PetscScalar *va;
2026ca15aa20SStefano Zampini   PetscScalar       *vb;
2027d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
20283a40ed3dSBarry Smith 
20293a40ed3dSBarry Smith   PetscFunctionBegin;
203033f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
203133f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
2032cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
20333a40ed3dSBarry Smith     PetscFunctionReturn(0);
20343a40ed3dSBarry Smith   }
2035e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
2036ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&va);CHKERRQ(ierr);
2037ca15aa20SStefano Zampini   ierr = MatDenseGetArray(B,&vb);CHKERRQ(ierr);
2038a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
20390dbb7854Svictorle     for (j=0; j<n; j++) {
2040ca15aa20SStefano Zampini       ierr = PetscArraycpy(vb+j*lda2,va+j*lda1,m);CHKERRQ(ierr);
2041a5ce6ee0Svictorle     }
2042a5ce6ee0Svictorle   } else {
2043ca15aa20SStefano Zampini     ierr = PetscArraycpy(vb,va,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2044a5ce6ee0Svictorle   }
2045ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(B,&vb);CHKERRQ(ierr);
2046ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&va);CHKERRQ(ierr);
2047ca15aa20SStefano Zampini   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2048ca15aa20SStefano Zampini   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2049273d9f13SBarry Smith   PetscFunctionReturn(0);
2050273d9f13SBarry Smith }
2051273d9f13SBarry Smith 
2052e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
2053273d9f13SBarry Smith {
2054dfbe8321SBarry Smith   PetscErrorCode ierr;
2055273d9f13SBarry Smith 
2056273d9f13SBarry Smith   PetscFunctionBegin;
2057273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
20583a40ed3dSBarry Smith   PetscFunctionReturn(0);
20594b0e389bSBarry Smith }
20604b0e389bSBarry Smith 
2061ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2062ba337c44SJed Brown {
2063ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2064ca15aa20SStefano Zampini   PetscScalar    *aa;
2065ca15aa20SStefano Zampini   PetscErrorCode ierr;
2066ba337c44SJed Brown 
2067ba337c44SJed Brown   PetscFunctionBegin;
2068ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2069ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2070ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2071ba337c44SJed Brown   PetscFunctionReturn(0);
2072ba337c44SJed Brown }
2073ba337c44SJed Brown 
2074ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2075ba337c44SJed Brown {
2076ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2077ca15aa20SStefano Zampini   PetscScalar    *aa;
2078ca15aa20SStefano Zampini   PetscErrorCode ierr;
2079ba337c44SJed Brown 
2080ba337c44SJed Brown   PetscFunctionBegin;
2081ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2082ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2083ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2084ba337c44SJed Brown   PetscFunctionReturn(0);
2085ba337c44SJed Brown }
2086ba337c44SJed Brown 
2087ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2088ba337c44SJed Brown {
2089ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2090ca15aa20SStefano Zampini   PetscScalar    *aa;
2091ca15aa20SStefano Zampini   PetscErrorCode ierr;
2092ba337c44SJed Brown 
2093ba337c44SJed Brown   PetscFunctionBegin;
2094ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2095ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
2096ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2097ba337c44SJed Brown   PetscFunctionReturn(0);
2098ba337c44SJed Brown }
2099284134d9SBarry Smith 
2100a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
2101150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
2102a9fe9ddaSSatish Balay {
2103a9fe9ddaSSatish Balay   PetscErrorCode ierr;
2104a9fe9ddaSSatish Balay 
2105a9fe9ddaSSatish Balay   PetscFunctionBegin;
2106a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
21073ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2108a9fe9ddaSSatish Balay     ierr = MatMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
21093ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2110a9fe9ddaSSatish Balay   }
21113ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2112ca15aa20SStefano Zampini   if ((*C)->ops->matmultnumeric) {
2113ca15aa20SStefano Zampini     ierr = (*(*C)->ops->matmultnumeric)(A,B,*C);CHKERRQ(ierr);
2114ca15aa20SStefano Zampini   } else {
2115a9fe9ddaSSatish Balay     ierr = MatMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
2116ca15aa20SStefano Zampini   }
21173ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2118a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2119a9fe9ddaSSatish Balay }
2120a9fe9ddaSSatish Balay 
2121a9fe9ddaSSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
2122a9fe9ddaSSatish Balay {
2123ee16a9a1SHong Zhang   PetscErrorCode ierr;
2124d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
2125ee16a9a1SHong Zhang   Mat            Cmat;
2126ca15aa20SStefano Zampini   PetscBool      flg;
2127a9fe9ddaSSatish Balay 
2128ee16a9a1SHong Zhang   PetscFunctionBegin;
2129ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
2130ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
2131ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
2132ca15aa20SStefano Zampini   ierr = MatSetType(Cmat,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
21330298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
2134ee16a9a1SHong Zhang   *C   = Cmat;
2135ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2136ee16a9a1SHong Zhang }
2137a9fe9ddaSSatish Balay 
2138a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2139a9fe9ddaSSatish Balay {
2140a9fe9ddaSSatish Balay   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2141a9fe9ddaSSatish Balay   Mat_SeqDense       *b = (Mat_SeqDense*)B->data;
2142a9fe9ddaSSatish Balay   Mat_SeqDense       *c = (Mat_SeqDense*)C->data;
21430805154bSBarry Smith   PetscBLASInt       m,n,k;
2144ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2145ca15aa20SStefano Zampini   PetscScalar       *cv;
2146a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2147c5df96a5SBarry Smith   PetscErrorCode    ierr;
2148fd4e9aacSBarry Smith   PetscBool         flg;
2149a9fe9ddaSSatish Balay 
2150a9fe9ddaSSatish Balay   PetscFunctionBegin;
2151fd4e9aacSBarry Smith   /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/
2152fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
2153fd4e9aacSBarry Smith   if (flg) {
2154fd4e9aacSBarry Smith     C->ops->matmultnumeric = MatMatMultNumeric_SeqAIJ_SeqDense;
2155fd4e9aacSBarry Smith     ierr = (*C->ops->matmultnumeric)(A,B,C);CHKERRQ(ierr);
2156fd4e9aacSBarry Smith     PetscFunctionReturn(0);
2157fd4e9aacSBarry Smith   }
2158a001520aSPierre Jolivet   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQBAIJ,&flg);CHKERRQ(ierr);
2159a001520aSPierre Jolivet   if (flg) {
2160a001520aSPierre Jolivet     C->ops->matmultnumeric = MatMatMultNumeric_SeqBAIJ_SeqDense;
2161a001520aSPierre Jolivet     ierr = (*C->ops->matmultnumeric)(A,B,C);CHKERRQ(ierr);
2162a001520aSPierre Jolivet     PetscFunctionReturn(0);
2163a001520aSPierre Jolivet   }
21648208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
21658208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2166c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
216749d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
2168ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
2169ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
2170ca15aa20SStefano Zampini   ierr = MatDenseGetArray(C,&cv);CHKERRQ(ierr);
2171ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
2172ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2173ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
2174ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
2175ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(C,&cv);CHKERRQ(ierr);
2176a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2177a9fe9ddaSSatish Balay }
2178a9fe9ddaSSatish Balay 
217969f65d41SStefano Zampini PetscErrorCode MatMatTransposeMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
218069f65d41SStefano Zampini {
218169f65d41SStefano Zampini   PetscErrorCode ierr;
218269f65d41SStefano Zampini 
218369f65d41SStefano Zampini   PetscFunctionBegin;
218469f65d41SStefano Zampini   if (scall == MAT_INITIAL_MATRIX) {
218569f65d41SStefano Zampini     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
218669f65d41SStefano Zampini     ierr = MatMatTransposeMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
218769f65d41SStefano Zampini     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
218869f65d41SStefano Zampini   }
218969f65d41SStefano Zampini   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
219069f65d41SStefano Zampini   ierr = MatMatTransposeMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
219169f65d41SStefano Zampini   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
219269f65d41SStefano Zampini   PetscFunctionReturn(0);
219369f65d41SStefano Zampini }
219469f65d41SStefano Zampini 
219569f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
219669f65d41SStefano Zampini {
219769f65d41SStefano Zampini   PetscErrorCode ierr;
219869f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
219969f65d41SStefano Zampini   Mat            Cmat;
2200ca15aa20SStefano Zampini   PetscBool      flg;
220169f65d41SStefano Zampini 
220269f65d41SStefano Zampini   PetscFunctionBegin;
220369f65d41SStefano Zampini   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
220469f65d41SStefano Zampini   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
2205ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
2206ca15aa20SStefano Zampini   ierr = MatSetType(Cmat,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
220769f65d41SStefano Zampini   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
220869f65d41SStefano Zampini   *C   = Cmat;
220969f65d41SStefano Zampini   PetscFunctionReturn(0);
221069f65d41SStefano Zampini }
221169f65d41SStefano Zampini 
221269f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
221369f65d41SStefano Zampini {
221469f65d41SStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
221569f65d41SStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
221669f65d41SStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
221769f65d41SStefano Zampini   PetscBLASInt   m,n,k;
221869f65d41SStefano Zampini   PetscScalar    _DOne=1.0,_DZero=0.0;
221969f65d41SStefano Zampini   PetscErrorCode ierr;
222069f65d41SStefano Zampini 
222169f65d41SStefano Zampini   PetscFunctionBegin;
222249d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
222349d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
222469f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
222549d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
222669f65d41SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2227ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
222869f65d41SStefano Zampini   PetscFunctionReturn(0);
222969f65d41SStefano Zampini }
223069f65d41SStefano Zampini 
223175648e8dSHong Zhang PetscErrorCode MatTransposeMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
2232a9fe9ddaSSatish Balay {
2233a9fe9ddaSSatish Balay   PetscErrorCode ierr;
2234a9fe9ddaSSatish Balay 
2235a9fe9ddaSSatish Balay   PetscFunctionBegin;
2236a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
22373ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
223875648e8dSHong Zhang     ierr = MatTransposeMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
22393ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2240a9fe9ddaSSatish Balay   }
22413ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
224275648e8dSHong Zhang   ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
22433ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2244a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2245a9fe9ddaSSatish Balay }
2246a9fe9ddaSSatish Balay 
224775648e8dSHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
2248a9fe9ddaSSatish Balay {
2249ee16a9a1SHong Zhang   PetscErrorCode ierr;
2250d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
2251ee16a9a1SHong Zhang   Mat            Cmat;
2252ca15aa20SStefano Zampini   PetscBool      flg;
2253a9fe9ddaSSatish Balay 
2254ee16a9a1SHong Zhang   PetscFunctionBegin;
2255ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
2256ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
2257ca15aa20SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
2258ca15aa20SStefano Zampini   ierr = MatSetType(Cmat,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
22590298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
2260ee16a9a1SHong Zhang   *C   = Cmat;
2261ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2262ee16a9a1SHong Zhang }
2263a9fe9ddaSSatish Balay 
226475648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2265a9fe9ddaSSatish Balay {
2266a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2267a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2268a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
22690805154bSBarry Smith   PetscBLASInt   m,n,k;
2270a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
2271c5df96a5SBarry Smith   PetscErrorCode ierr;
2272a9fe9ddaSSatish Balay 
2273a9fe9ddaSSatish Balay   PetscFunctionBegin;
22748208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
22758208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2276c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
227749d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
22785ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2279ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2280a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2281a9fe9ddaSSatish Balay }
2282985db425SBarry Smith 
2283e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2284985db425SBarry Smith {
2285985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2286985db425SBarry Smith   PetscErrorCode     ierr;
2287d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2288985db425SBarry Smith   PetscScalar        *x;
2289ca15aa20SStefano Zampini   const PetscScalar *aa;
2290985db425SBarry Smith 
2291985db425SBarry Smith   PetscFunctionBegin;
2292e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2293985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2294985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2295ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2296e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2297985db425SBarry Smith   for (i=0; i<m; i++) {
2298985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2299985db425SBarry Smith     for (j=1; j<n; j++) {
2300ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2301985db425SBarry Smith     }
2302985db425SBarry Smith   }
2303ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2304985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2305985db425SBarry Smith   PetscFunctionReturn(0);
2306985db425SBarry Smith }
2307985db425SBarry Smith 
2308e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2309985db425SBarry Smith {
2310985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2311985db425SBarry Smith   PetscErrorCode    ierr;
2312d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2313985db425SBarry Smith   PetscScalar       *x;
2314985db425SBarry Smith   PetscReal         atmp;
2315ca15aa20SStefano Zampini   const PetscScalar *aa;
2316985db425SBarry Smith 
2317985db425SBarry Smith   PetscFunctionBegin;
2318e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2319985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2320985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2321ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2322e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2323985db425SBarry Smith   for (i=0; i<m; i++) {
23249189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2325985db425SBarry Smith     for (j=1; j<n; j++) {
2326ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2327985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2328985db425SBarry Smith     }
2329985db425SBarry Smith   }
2330ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2331985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2332985db425SBarry Smith   PetscFunctionReturn(0);
2333985db425SBarry Smith }
2334985db425SBarry Smith 
2335e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2336985db425SBarry Smith {
2337985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2338985db425SBarry Smith   PetscErrorCode    ierr;
2339d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2340985db425SBarry Smith   PetscScalar       *x;
2341ca15aa20SStefano Zampini   const PetscScalar *aa;
2342985db425SBarry Smith 
2343985db425SBarry Smith   PetscFunctionBegin;
2344e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2345ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2346985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2347985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2348e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2349985db425SBarry Smith   for (i=0; i<m; i++) {
2350985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2351985db425SBarry Smith     for (j=1; j<n; j++) {
2352ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2353985db425SBarry Smith     }
2354985db425SBarry Smith   }
2355985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2356ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2357985db425SBarry Smith   PetscFunctionReturn(0);
2358985db425SBarry Smith }
2359985db425SBarry Smith 
2360e0877f53SBarry Smith static PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
23618d0534beSBarry Smith {
23628d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
23638d0534beSBarry Smith   PetscErrorCode    ierr;
23648d0534beSBarry Smith   PetscScalar       *x;
2365ca15aa20SStefano Zampini   const PetscScalar *aa;
23668d0534beSBarry Smith 
23678d0534beSBarry Smith   PetscFunctionBegin;
2368e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2369ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
23708d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2371ca15aa20SStefano Zampini   ierr = PetscArraycpy(x,aa+col*a->lda,A->rmap->n);CHKERRQ(ierr);
23728d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2373ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
23748d0534beSBarry Smith   PetscFunctionReturn(0);
23758d0534beSBarry Smith }
23768d0534beSBarry Smith 
23770716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
23780716a85fSBarry Smith {
23790716a85fSBarry Smith   PetscErrorCode    ierr;
23800716a85fSBarry Smith   PetscInt          i,j,m,n;
23811683a169SBarry Smith   const PetscScalar *a;
23820716a85fSBarry Smith 
23830716a85fSBarry Smith   PetscFunctionBegin;
23840716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2385580bdb30SBarry Smith   ierr = PetscArrayzero(norms,n);CHKERRQ(ierr);
23861683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&a);CHKERRQ(ierr);
23870716a85fSBarry Smith   if (type == NORM_2) {
23880716a85fSBarry Smith     for (i=0; i<n; i++) {
23890716a85fSBarry Smith       for (j=0; j<m; j++) {
23900716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
23910716a85fSBarry Smith       }
23920716a85fSBarry Smith       a += m;
23930716a85fSBarry Smith     }
23940716a85fSBarry Smith   } else if (type == NORM_1) {
23950716a85fSBarry Smith     for (i=0; i<n; i++) {
23960716a85fSBarry Smith       for (j=0; j<m; j++) {
23970716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
23980716a85fSBarry Smith       }
23990716a85fSBarry Smith       a += m;
24000716a85fSBarry Smith     }
24010716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
24020716a85fSBarry Smith     for (i=0; i<n; i++) {
24030716a85fSBarry Smith       for (j=0; j<m; j++) {
24040716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
24050716a85fSBarry Smith       }
24060716a85fSBarry Smith       a += m;
24070716a85fSBarry Smith     }
2408ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
24091683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&a);CHKERRQ(ierr);
24100716a85fSBarry Smith   if (type == NORM_2) {
24118f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
24120716a85fSBarry Smith   }
24130716a85fSBarry Smith   PetscFunctionReturn(0);
24140716a85fSBarry Smith }
24150716a85fSBarry Smith 
241673a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
241773a71a0fSBarry Smith {
241873a71a0fSBarry Smith   PetscErrorCode ierr;
241973a71a0fSBarry Smith   PetscScalar    *a;
242073a71a0fSBarry Smith   PetscInt       m,n,i;
242173a71a0fSBarry Smith 
242273a71a0fSBarry Smith   PetscFunctionBegin;
242373a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
24248c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
242573a71a0fSBarry Smith   for (i=0; i<m*n; i++) {
242673a71a0fSBarry Smith     ierr = PetscRandomGetValue(rctx,a+i);CHKERRQ(ierr);
242773a71a0fSBarry Smith   }
24288c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
242973a71a0fSBarry Smith   PetscFunctionReturn(0);
243073a71a0fSBarry Smith }
243173a71a0fSBarry Smith 
24323b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
24333b49f96aSBarry Smith {
24343b49f96aSBarry Smith   PetscFunctionBegin;
24353b49f96aSBarry Smith   *missing = PETSC_FALSE;
24363b49f96aSBarry Smith   PetscFunctionReturn(0);
24373b49f96aSBarry Smith }
243873a71a0fSBarry Smith 
2439ca15aa20SStefano Zampini /* vals is not const */
2440af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
244186aefd0dSHong Zhang {
2442ca15aa20SStefano Zampini   PetscErrorCode ierr;
244386aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2444ca15aa20SStefano Zampini   PetscScalar    *v;
244586aefd0dSHong Zhang 
244686aefd0dSHong Zhang   PetscFunctionBegin;
244786aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2448ca15aa20SStefano Zampini   ierr  = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2449ca15aa20SStefano Zampini   *vals = v+col*a->lda;
2450ca15aa20SStefano Zampini   ierr  = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
245186aefd0dSHong Zhang   PetscFunctionReturn(0);
245286aefd0dSHong Zhang }
245386aefd0dSHong Zhang 
2454af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
245586aefd0dSHong Zhang {
245686aefd0dSHong Zhang   PetscFunctionBegin;
245786aefd0dSHong Zhang   *vals = 0; /* user cannot accidently use the array later */
245886aefd0dSHong Zhang   PetscFunctionReturn(0);
245986aefd0dSHong Zhang }
2460abc3b08eSStefano Zampini 
2461289bc588SBarry Smith /* -------------------------------------------------------------------*/
2462a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2463905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2464905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2465905e6a2fSBarry Smith                                         MatMult_SeqDense,
246697304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
24677c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
24687c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2469db4efbfdSBarry Smith                                         0,
2470db4efbfdSBarry Smith                                         0,
2471db4efbfdSBarry Smith                                         0,
2472db4efbfdSBarry Smith                                 /* 10*/ 0,
2473905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2474905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
247541f059aeSBarry Smith                                         MatSOR_SeqDense,
2476ec8511deSBarry Smith                                         MatTranspose_SeqDense,
247797304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2478905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2479905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2480905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2481905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2482c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2483c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2484905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2485905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2486d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2487db4efbfdSBarry Smith                                         0,
2488db4efbfdSBarry Smith                                         0,
2489db4efbfdSBarry Smith                                         0,
2490db4efbfdSBarry Smith                                         0,
24914994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2492273d9f13SBarry Smith                                         0,
2493905e6a2fSBarry Smith                                         0,
249473a71a0fSBarry Smith                                         0,
249573a71a0fSBarry Smith                                         0,
2496d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2497a5ae1ecdSBarry Smith                                         0,
2498a5ae1ecdSBarry Smith                                         0,
2499a5ae1ecdSBarry Smith                                         0,
2500a5ae1ecdSBarry Smith                                         0,
2501d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
25027dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2503a5ae1ecdSBarry Smith                                         0,
25044b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2505a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2506d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2507a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
25087d68702bSBarry Smith                                         MatShift_Basic,
2509a5ae1ecdSBarry Smith                                         0,
25103f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
251173a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2512a5ae1ecdSBarry Smith                                         0,
2513a5ae1ecdSBarry Smith                                         0,
2514a5ae1ecdSBarry Smith                                         0,
2515a5ae1ecdSBarry Smith                                         0,
2516d519adbfSMatthew Knepley                                 /* 54*/ 0,
2517a5ae1ecdSBarry Smith                                         0,
2518a5ae1ecdSBarry Smith                                         0,
2519a5ae1ecdSBarry Smith                                         0,
2520a5ae1ecdSBarry Smith                                         0,
2521d519adbfSMatthew Knepley                                 /* 59*/ 0,
2522e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2523e03a110bSBarry Smith                                         MatView_SeqDense,
2524357abbc8SBarry Smith                                         0,
252597304618SKris Buschelman                                         0,
2526d519adbfSMatthew Knepley                                 /* 64*/ 0,
252797304618SKris Buschelman                                         0,
252897304618SKris Buschelman                                         0,
252997304618SKris Buschelman                                         0,
253097304618SKris Buschelman                                         0,
2531d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
253297304618SKris Buschelman                                         0,
253397304618SKris Buschelman                                         0,
253497304618SKris Buschelman                                         0,
253597304618SKris Buschelman                                         0,
2536d519adbfSMatthew Knepley                                 /* 74*/ 0,
253797304618SKris Buschelman                                         0,
253897304618SKris Buschelman                                         0,
253997304618SKris Buschelman                                         0,
254097304618SKris Buschelman                                         0,
2541d519adbfSMatthew Knepley                                 /* 79*/ 0,
254297304618SKris Buschelman                                         0,
254397304618SKris Buschelman                                         0,
254497304618SKris Buschelman                                         0,
25455bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2546865e5f61SKris Buschelman                                         0,
25471cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2548865e5f61SKris Buschelman                                         0,
2549865e5f61SKris Buschelman                                         0,
2550865e5f61SKris Buschelman                                         0,
2551d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqDense_SeqDense,
2552a9fe9ddaSSatish Balay                                         MatMatMultSymbolic_SeqDense_SeqDense,
2553a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2554abc3b08eSStefano Zampini                                         MatPtAP_SeqDense_SeqDense,
2555abc3b08eSStefano Zampini                                         MatPtAPSymbolic_SeqDense_SeqDense,
2556abc3b08eSStefano Zampini                                 /* 94*/ MatPtAPNumeric_SeqDense_SeqDense,
255769f65d41SStefano Zampini                                         MatMatTransposeMult_SeqDense_SeqDense,
255869f65d41SStefano Zampini                                         MatMatTransposeMultSymbolic_SeqDense_SeqDense,
255969f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2560284134d9SBarry Smith                                         0,
2561d519adbfSMatthew Knepley                                 /* 99*/ 0,
2562284134d9SBarry Smith                                         0,
2563284134d9SBarry Smith                                         0,
2564ba337c44SJed Brown                                         MatConjugate_SeqDense,
2565f73d5cc4SBarry Smith                                         0,
2566ba337c44SJed Brown                                 /*104*/ 0,
2567ba337c44SJed Brown                                         MatRealPart_SeqDense,
2568ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2569985db425SBarry Smith                                         0,
2570985db425SBarry Smith                                         0,
25718208b9aeSStefano Zampini                                 /*109*/ 0,
2572985db425SBarry Smith                                         0,
25738d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2574aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
25753b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2576aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2577aabbc4fbSShri Abhyankar                                         0,
2578aabbc4fbSShri Abhyankar                                         0,
2579aabbc4fbSShri Abhyankar                                         0,
2580aabbc4fbSShri Abhyankar                                         0,
2581aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2582aabbc4fbSShri Abhyankar                                         0,
2583aabbc4fbSShri Abhyankar                                         0,
25840716a85fSBarry Smith                                         0,
25850716a85fSBarry Smith                                         0,
25860716a85fSBarry Smith                                 /*124*/ 0,
25875df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
25885df89d91SHong Zhang                                         0,
25895df89d91SHong Zhang                                         0,
25905df89d91SHong Zhang                                         0,
25915df89d91SHong Zhang                                 /*129*/ 0,
259275648e8dSHong Zhang                                         MatTransposeMatMult_SeqDense_SeqDense,
259375648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqDense_SeqDense,
259475648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
25953964eb88SJed Brown                                         0,
25963964eb88SJed Brown                                 /*134*/ 0,
25973964eb88SJed Brown                                         0,
25983964eb88SJed Brown                                         0,
25993964eb88SJed Brown                                         0,
26003964eb88SJed Brown                                         0,
26013964eb88SJed Brown                                 /*139*/ 0,
2602f9426fe0SMark Adams                                         0,
2603d528f656SJakub Kruzik                                         0,
2604d528f656SJakub Kruzik                                         0,
2605d528f656SJakub Kruzik                                         0,
2606d528f656SJakub Kruzik                                 /*144*/ MatCreateMPIMatConcatenateSeqMat_SeqDense
2607985db425SBarry Smith };
260890ace30eSBarry Smith 
26094b828684SBarry Smith /*@C
2610fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2611d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2612d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2613289bc588SBarry Smith 
2614d083f849SBarry Smith    Collective
2615db81eaa0SLois Curfman McInnes 
261620563c6bSBarry Smith    Input Parameters:
2617db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
26180c775827SLois Curfman McInnes .  m - number of rows
261918f449edSLois Curfman McInnes .  n - number of columns
26200298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2621dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
262220563c6bSBarry Smith 
262320563c6bSBarry Smith    Output Parameter:
262444cd7ae7SLois Curfman McInnes .  A - the matrix
262520563c6bSBarry Smith 
2626b259b22eSLois Curfman McInnes    Notes:
262718f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
262818f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
26290298fd71SBarry Smith    set data=NULL.
263018f449edSLois Curfman McInnes 
2631027ccd11SLois Curfman McInnes    Level: intermediate
2632027ccd11SLois Curfman McInnes 
263369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
263420563c6bSBarry Smith @*/
26357087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2636289bc588SBarry Smith {
2637dfbe8321SBarry Smith   PetscErrorCode ierr;
26383b2fbd54SBarry Smith 
26393a40ed3dSBarry Smith   PetscFunctionBegin;
2640f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2641f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2642273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2643273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2644273d9f13SBarry Smith   PetscFunctionReturn(0);
2645273d9f13SBarry Smith }
2646273d9f13SBarry Smith 
2647273d9f13SBarry Smith /*@C
2648273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2649273d9f13SBarry Smith 
2650d083f849SBarry Smith    Collective
2651273d9f13SBarry Smith 
2652273d9f13SBarry Smith    Input Parameters:
26531c4f3114SJed Brown +  B - the matrix
26540298fd71SBarry Smith -  data - the array (or NULL)
2655273d9f13SBarry Smith 
2656273d9f13SBarry Smith    Notes:
2657273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2658273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2659284134d9SBarry Smith    need not call this routine.
2660273d9f13SBarry Smith 
2661273d9f13SBarry Smith    Level: intermediate
2662273d9f13SBarry Smith 
266369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA()
2664867c911aSBarry Smith 
2665273d9f13SBarry Smith @*/
26667087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2667273d9f13SBarry Smith {
26684ac538c5SBarry Smith   PetscErrorCode ierr;
2669a23d5eceSKris Buschelman 
2670a23d5eceSKris Buschelman   PetscFunctionBegin;
26714ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2672a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2673a23d5eceSKris Buschelman }
2674a23d5eceSKris Buschelman 
26757087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2676a23d5eceSKris Buschelman {
2677273d9f13SBarry Smith   Mat_SeqDense   *b;
2678dfbe8321SBarry Smith   PetscErrorCode ierr;
2679273d9f13SBarry Smith 
2680273d9f13SBarry Smith   PetscFunctionBegin;
2681273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2682a868139aSShri Abhyankar 
268334ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
268434ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
268534ef9618SShri Abhyankar 
2686273d9f13SBarry Smith   b       = (Mat_SeqDense*)B->data;
268786d161a7SShri Abhyankar   b->Mmax = B->rmap->n;
268886d161a7SShri Abhyankar   b->Nmax = B->cmap->n;
268986d161a7SShri Abhyankar   if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n;
269086d161a7SShri Abhyankar 
2691220afb94SBarry Smith   ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr);
26929e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
26939e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2694e92229d0SSatish Balay     ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr);
26953bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
26962205254eSKarl Rupp 
26979e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2698273d9f13SBarry Smith   } else { /* user-allocated storage */
26999e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2700273d9f13SBarry Smith     b->v          = data;
2701273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2702273d9f13SBarry Smith   }
27030450473dSBarry Smith   B->assembled = PETSC_TRUE;
2704273d9f13SBarry Smith   PetscFunctionReturn(0);
2705273d9f13SBarry Smith }
2706273d9f13SBarry Smith 
270765b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2708cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
27098baccfbdSHong Zhang {
2710d77f618aSHong Zhang   Mat               mat_elemental;
2711d77f618aSHong Zhang   PetscErrorCode    ierr;
27121683a169SBarry Smith   const PetscScalar *array;
27131683a169SBarry Smith   PetscScalar       *v_colwise;
2714d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2715d77f618aSHong Zhang 
27168baccfbdSHong Zhang   PetscFunctionBegin;
2717d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
27181683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&array);CHKERRQ(ierr);
2719d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2720d77f618aSHong Zhang   k = 0;
2721d77f618aSHong Zhang   for (j=0; j<N; j++) {
2722d77f618aSHong Zhang     cols[j] = j;
2723d77f618aSHong Zhang     for (i=0; i<M; i++) {
2724d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2725d77f618aSHong Zhang     }
2726d77f618aSHong Zhang   }
2727d77f618aSHong Zhang   for (i=0; i<M; i++) {
2728d77f618aSHong Zhang     rows[i] = i;
2729d77f618aSHong Zhang   }
27301683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&array);CHKERRQ(ierr);
2731d77f618aSHong Zhang 
2732d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2733d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2734d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2735d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2736d77f618aSHong Zhang 
2737d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2738d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2739d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2740d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2741d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2742d77f618aSHong Zhang 
2743511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
274428be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2745d77f618aSHong Zhang   } else {
2746d77f618aSHong Zhang     *newmat = mat_elemental;
2747d77f618aSHong Zhang   }
27488baccfbdSHong Zhang   PetscFunctionReturn(0);
27498baccfbdSHong Zhang }
275065b80a83SHong Zhang #endif
27518baccfbdSHong Zhang 
27521b807ce4Svictorle /*@C
27531b807ce4Svictorle   MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array
27541b807ce4Svictorle 
27551b807ce4Svictorle   Input parameter:
27561b807ce4Svictorle + A - the matrix
27571b807ce4Svictorle - lda - the leading dimension
27581b807ce4Svictorle 
27591b807ce4Svictorle   Notes:
2760867c911aSBarry Smith   This routine is to be used in conjunction with MatSeqDenseSetPreallocation();
27611b807ce4Svictorle   it asserts that the preallocation has a leading dimension (the LDA parameter
27621b807ce4Svictorle   of Blas and Lapack fame) larger than M, the first dimension of the matrix.
27631b807ce4Svictorle 
27641b807ce4Svictorle   Level: intermediate
27651b807ce4Svictorle 
2766284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize()
2767867c911aSBarry Smith 
27681b807ce4Svictorle @*/
27697087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetLDA(Mat B,PetscInt lda)
27701b807ce4Svictorle {
27711b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
277221a2c019SBarry Smith 
27731b807ce4Svictorle   PetscFunctionBegin;
2774e32f2f54SBarry 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);
27751b807ce4Svictorle   b->lda       = lda;
277621a2c019SBarry Smith   b->changelda = PETSC_FALSE;
277721a2c019SBarry Smith   b->Mmax      = PetscMax(b->Mmax,lda);
27781b807ce4Svictorle   PetscFunctionReturn(0);
27791b807ce4Svictorle }
27801b807ce4Svictorle 
2781d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
2782d528f656SJakub Kruzik {
2783d528f656SJakub Kruzik   PetscErrorCode ierr;
2784d528f656SJakub Kruzik   PetscMPIInt    size;
2785d528f656SJakub Kruzik 
2786d528f656SJakub Kruzik   PetscFunctionBegin;
2787d528f656SJakub Kruzik   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2788d528f656SJakub Kruzik   if (size == 1) {
2789d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
2790d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
2791d528f656SJakub Kruzik     } else {
2792d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2793d528f656SJakub Kruzik     }
2794d528f656SJakub Kruzik   } else {
2795d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
2796d528f656SJakub Kruzik   }
2797d528f656SJakub Kruzik   PetscFunctionReturn(0);
2798d528f656SJakub Kruzik }
2799d528f656SJakub Kruzik 
28000bad9183SKris Buschelman /*MC
2801fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
28020bad9183SKris Buschelman 
28030bad9183SKris Buschelman    Options Database Keys:
28040bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
28050bad9183SKris Buschelman 
28060bad9183SKris Buschelman   Level: beginner
28070bad9183SKris Buschelman 
280889665df3SBarry Smith .seealso: MatCreateSeqDense()
280989665df3SBarry Smith 
28100bad9183SKris Buschelman M*/
2811ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
2812273d9f13SBarry Smith {
2813273d9f13SBarry Smith   Mat_SeqDense   *b;
2814dfbe8321SBarry Smith   PetscErrorCode ierr;
28157c334f02SBarry Smith   PetscMPIInt    size;
2816273d9f13SBarry Smith 
2817273d9f13SBarry Smith   PetscFunctionBegin;
2818ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
2819e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
282055659b69SBarry Smith 
2821b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
2822549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
282344cd7ae7SLois Curfman McInnes   B->data = (void*)b;
282418f449edSLois Curfman McInnes 
2825273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
28264e220ebcSLois Curfman McInnes 
282749a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
2828bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
28298572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2830d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
2831d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
28328572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2833715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2834bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
28358baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
28368baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
28378baccfbdSHong Zhang #endif
28382bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
28392bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA);CHKERRQ(ierr);
2840a4af7ca8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijcusparse_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
28412bf066beSStefano Zampini #endif
2842bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
2843bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaij_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2844a4af7ca8SStefano Zampini #if defined(PETSC_HAVE_VIENNACL)
2845a4af7ca8SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijviennacl_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2846a4af7ca8SStefano Zampini #endif
2847bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2848bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2849a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqbaij_seqdense_C",MatMatMult_SeqBAIJ_SeqDense);CHKERRQ(ierr);
2850a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqbaij_seqdense_C",MatMatMultSymbolic_SeqBAIJ_SeqDense);CHKERRQ(ierr);
2851a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqbaij_seqdense_C",MatMatMultNumeric_SeqBAIJ_SeqDense);CHKERRQ(ierr);
2852abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaij_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
28534099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijperm_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
28544099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijperm_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28554099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijperm_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
28564099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijperm_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
2857e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijsell_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2858e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijsell_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2859e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijsell_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2860e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijsell_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
286196e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijmkl_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
286296e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijmkl_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
286396e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijmkl_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
286496e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijmkl_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
286596e6d5c4SRichard Tran Mills 
28663bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaij_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
28673bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28683bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
28694099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijperm_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
28704099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28714099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2872e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijsell_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2873e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2874e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
287596e6d5c4SRichard Tran Mills 
287696e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijmkl_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
287796e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
287896e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2879af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
2880af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
288117667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
28823a40ed3dSBarry Smith   PetscFunctionReturn(0);
2883289bc588SBarry Smith }
288486aefd0dSHong Zhang 
288586aefd0dSHong Zhang /*@C
2886af53bab2SHong 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.
288786aefd0dSHong Zhang 
288886aefd0dSHong Zhang    Not Collective
288986aefd0dSHong Zhang 
289086aefd0dSHong Zhang    Input Parameter:
289186aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
289286aefd0dSHong Zhang -  col - column index
289386aefd0dSHong Zhang 
289486aefd0dSHong Zhang    Output Parameter:
289586aefd0dSHong Zhang .  vals - pointer to the data
289686aefd0dSHong Zhang 
289786aefd0dSHong Zhang    Level: intermediate
289886aefd0dSHong Zhang 
289986aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
290086aefd0dSHong Zhang @*/
290186aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
290286aefd0dSHong Zhang {
290386aefd0dSHong Zhang   PetscErrorCode ierr;
290486aefd0dSHong Zhang 
290586aefd0dSHong Zhang   PetscFunctionBegin;
290686aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
290786aefd0dSHong Zhang   PetscFunctionReturn(0);
290886aefd0dSHong Zhang }
290986aefd0dSHong Zhang 
291086aefd0dSHong Zhang /*@C
291186aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
291286aefd0dSHong Zhang 
291386aefd0dSHong Zhang    Not Collective
291486aefd0dSHong Zhang 
291586aefd0dSHong Zhang    Input Parameter:
291686aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
291786aefd0dSHong Zhang 
291886aefd0dSHong Zhang    Output Parameter:
291986aefd0dSHong Zhang .  vals - pointer to the data
292086aefd0dSHong Zhang 
292186aefd0dSHong Zhang    Level: intermediate
292286aefd0dSHong Zhang 
292386aefd0dSHong Zhang .seealso: MatDenseGetColumn()
292486aefd0dSHong Zhang @*/
292586aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
292686aefd0dSHong Zhang {
292786aefd0dSHong Zhang   PetscErrorCode ierr;
292886aefd0dSHong Zhang 
292986aefd0dSHong Zhang   PetscFunctionBegin;
293086aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
293186aefd0dSHong Zhang   PetscFunctionReturn(0);
293286aefd0dSHong Zhang }
2933