xref: /petsc/src/mat/impls/dense/seq/dense.c (revision a001520a128cc7d56acd6c85bdd4bb5f9c40bef5)
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 
118c178816SStefano Zampini static 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;
158c178816SStefano Zampini 
168c178816SStefano Zampini   PetscFunctionBegin;
178c178816SStefano Zampini   if (A->rmap->n != A->cmap->n) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot symmetrize a rectangular matrix");
188c178816SStefano Zampini   if (!hermitian) {
198c178816SStefano Zampini     for (k=0;k<n;k++) {
208c178816SStefano Zampini       for (j=k;j<n;j++) {
218c178816SStefano Zampini         mat->v[j*mat->lda + k] = mat->v[k*mat->lda + j];
228c178816SStefano Zampini       }
238c178816SStefano Zampini     }
248c178816SStefano Zampini   } else {
258c178816SStefano Zampini     for (k=0;k<n;k++) {
268c178816SStefano Zampini       for (j=k;j<n;j++) {
278c178816SStefano Zampini         mat->v[j*mat->lda + k] = PetscConj(mat->v[k*mat->lda + j]);
288c178816SStefano Zampini       }
298c178816SStefano Zampini     }
308c178816SStefano Zampini   }
318c178816SStefano Zampini   PetscFunctionReturn(0);
328c178816SStefano Zampini }
338c178816SStefano Zampini 
3405709791SSatish Balay PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A)
358c178816SStefano Zampini {
368c178816SStefano Zampini #if defined(PETSC_MISSING_LAPACK_POTRF)
378c178816SStefano Zampini   PetscFunctionBegin;
388c178816SStefano Zampini   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF - Lapack routine is unavailable.");
398c178816SStefano Zampini #else
408c178816SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
418c178816SStefano Zampini   PetscErrorCode ierr;
428c178816SStefano Zampini   PetscBLASInt   info,n;
438c178816SStefano Zampini 
448c178816SStefano Zampini   PetscFunctionBegin;
458c178816SStefano Zampini   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
468c178816SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
478c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
488c178816SStefano Zampini     if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
498c178816SStefano Zampini     if (!mat->fwork) {
508c178816SStefano Zampini       mat->lfwork = n;
518c178816SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
528c178816SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
538c178816SStefano Zampini     }
5400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
558c178816SStefano Zampini     PetscStackCallBLAS("LAPACKgetri",LAPACKgetri_(&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
5600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
578c178816SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr); /* TODO CHECK FLOPS */
588c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
598c178816SStefano Zampini     if (A->spd) {
6000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
618c178816SStefano Zampini       PetscStackCallBLAS("LAPACKpotri",LAPACKpotri_("L",&n,mat->v,&mat->lda,&info));
6200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
638c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
648c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
658c178816SStefano Zampini     } else if (A->hermitian) {
668c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
678c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
6800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
698c178816SStefano Zampini       PetscStackCallBLAS("LAPACKhetri",LAPACKhetri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
7000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
718c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
728c178816SStefano Zampini #endif
738c178816SStefano Zampini     } else { /* symmetric case */
748c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
758c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
7600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
778c178816SStefano Zampini       PetscStackCallBLAS("LAPACKsytri",LAPACKsytri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
7800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
798c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_FALSE);CHKERRQ(ierr);
808c178816SStefano Zampini     }
818c178816SStefano Zampini     if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad Inversion: zero pivot in row %D",(PetscInt)info-1);
828c178816SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr); /* TODO CHECK FLOPS */
838c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
848c178816SStefano Zampini #endif
858c178816SStefano Zampini 
868c178816SStefano Zampini   A->ops->solve             = NULL;
878c178816SStefano Zampini   A->ops->matsolve          = NULL;
888c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
898c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
908c178816SStefano Zampini   A->ops->solveadd          = NULL;
918c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
928c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
938c178816SStefano Zampini   ierr                      = PetscFree(A->solvertype);CHKERRQ(ierr);
948c178816SStefano Zampini   PetscFunctionReturn(0);
958c178816SStefano Zampini }
968c178816SStefano Zampini 
973f49a652SStefano Zampini PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
983f49a652SStefano Zampini {
993f49a652SStefano Zampini   PetscErrorCode    ierr;
1003f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1013f49a652SStefano Zampini   PetscInt          m  = l->lda, n = A->cmap->n,r = A->rmap->n, i,j;
1023f49a652SStefano Zampini   PetscScalar       *slot,*bb;
1033f49a652SStefano Zampini   const PetscScalar *xx;
1043f49a652SStefano Zampini 
1053f49a652SStefano Zampini   PetscFunctionBegin;
1063f49a652SStefano Zampini #if defined(PETSC_USE_DEBUG)
1073f49a652SStefano Zampini   for (i=0; i<N; i++) {
1083f49a652SStefano Zampini     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1093f49a652SStefano 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);
1103f49a652SStefano 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);
1113f49a652SStefano Zampini   }
1123f49a652SStefano Zampini #endif
1133f49a652SStefano Zampini 
1143f49a652SStefano Zampini   /* fix right hand side if needed */
1153f49a652SStefano Zampini   if (x && b) {
1166c4d906cSStefano Zampini     Vec xt;
1176c4d906cSStefano Zampini 
1186c4d906cSStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1196c4d906cSStefano Zampini     ierr = VecDuplicate(x,&xt);CHKERRQ(ierr);
1206c4d906cSStefano Zampini     ierr = VecCopy(x,xt);CHKERRQ(ierr);
1216c4d906cSStefano Zampini     ierr = VecScale(xt,-1.0);CHKERRQ(ierr);
1226c4d906cSStefano Zampini     ierr = MatMultAdd(A,xt,b,b);CHKERRQ(ierr);
1236c4d906cSStefano Zampini     ierr = VecDestroy(&xt);CHKERRQ(ierr);
1243f49a652SStefano Zampini     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1253f49a652SStefano Zampini     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
1263f49a652SStefano Zampini     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
1273f49a652SStefano Zampini     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1283f49a652SStefano Zampini     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
1293f49a652SStefano Zampini   }
1303f49a652SStefano Zampini 
1313f49a652SStefano Zampini   for (i=0; i<N; i++) {
1323f49a652SStefano Zampini     slot = l->v + rows[i]*m;
133580bdb30SBarry Smith     ierr = PetscArrayzero(slot,r);CHKERRQ(ierr);
1343f49a652SStefano Zampini   }
1353f49a652SStefano Zampini   for (i=0; i<N; i++) {
1363f49a652SStefano Zampini     slot = l->v + rows[i];
1373f49a652SStefano Zampini     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
1383f49a652SStefano Zampini   }
1393f49a652SStefano Zampini   if (diag != 0.0) {
1403f49a652SStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1413f49a652SStefano Zampini     for (i=0; i<N; i++) {
1423f49a652SStefano Zampini       slot  = l->v + (m+1)*rows[i];
1433f49a652SStefano Zampini       *slot = diag;
1443f49a652SStefano Zampini     }
1453f49a652SStefano Zampini   }
1463f49a652SStefano Zampini   PetscFunctionReturn(0);
1473f49a652SStefano Zampini }
1483f49a652SStefano Zampini 
149abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C)
150abc3b08eSStefano Zampini {
151abc3b08eSStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)(C->data);
152abc3b08eSStefano Zampini   PetscErrorCode ierr;
153abc3b08eSStefano Zampini 
154abc3b08eSStefano Zampini   PetscFunctionBegin;
155abc3b08eSStefano Zampini   ierr = MatMatMultNumeric_SeqDense_SeqDense(A,P,c->ptapwork);CHKERRQ(ierr);
156abc3b08eSStefano Zampini   ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(P,c->ptapwork,C);CHKERRQ(ierr);
157abc3b08eSStefano Zampini   PetscFunctionReturn(0);
158abc3b08eSStefano Zampini }
159abc3b08eSStefano Zampini 
160abc3b08eSStefano Zampini PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat *C)
161abc3b08eSStefano Zampini {
162abc3b08eSStefano Zampini   Mat_SeqDense   *c;
163abc3b08eSStefano Zampini   PetscErrorCode ierr;
164abc3b08eSStefano Zampini 
165abc3b08eSStefano Zampini   PetscFunctionBegin;
166abc3b08eSStefano Zampini   ierr = MatCreateSeqDense(PetscObjectComm((PetscObject)A),P->cmap->N,P->cmap->N,NULL,C);CHKERRQ(ierr);
167abc3b08eSStefano Zampini   c = (Mat_SeqDense*)((*C)->data);
168abc3b08eSStefano Zampini   ierr = MatCreateSeqDense(PetscObjectComm((PetscObject)A),A->rmap->N,P->cmap->N,NULL,&c->ptapwork);CHKERRQ(ierr);
169abc3b08eSStefano Zampini   PetscFunctionReturn(0);
170abc3b08eSStefano Zampini }
171abc3b08eSStefano Zampini 
172150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatPtAP_SeqDense_SeqDense(Mat A,Mat P,MatReuse reuse,PetscReal fill,Mat *C)
173abc3b08eSStefano Zampini {
174abc3b08eSStefano Zampini   PetscErrorCode ierr;
175abc3b08eSStefano Zampini 
176abc3b08eSStefano Zampini   PetscFunctionBegin;
177abc3b08eSStefano Zampini   if (reuse == MAT_INITIAL_MATRIX) {
178abc3b08eSStefano Zampini     ierr = MatPtAPSymbolic_SeqDense_SeqDense(A,P,fill,C);CHKERRQ(ierr);
179abc3b08eSStefano Zampini   }
180abc3b08eSStefano Zampini   ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
181abc3b08eSStefano Zampini   ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr);
182abc3b08eSStefano Zampini   ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr);
183abc3b08eSStefano Zampini   PetscFunctionReturn(0);
184abc3b08eSStefano Zampini }
185abc3b08eSStefano Zampini 
186cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
187b49cda9fSStefano Zampini {
188a13144ffSStefano Zampini   Mat            B = NULL;
189b49cda9fSStefano Zampini   Mat_SeqAIJ     *a = (Mat_SeqAIJ*)A->data;
190b49cda9fSStefano Zampini   Mat_SeqDense   *b;
191b49cda9fSStefano Zampini   PetscErrorCode ierr;
192b49cda9fSStefano Zampini   PetscInt       *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i;
193b49cda9fSStefano Zampini   MatScalar      *av=a->a;
194a13144ffSStefano Zampini   PetscBool      isseqdense;
195b49cda9fSStefano Zampini 
196b49cda9fSStefano Zampini   PetscFunctionBegin;
197a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
198a13144ffSStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense);CHKERRQ(ierr);
199a32993e3SJed Brown     if (!isseqdense) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type_name);
200a13144ffSStefano Zampini   }
201a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
202b49cda9fSStefano Zampini     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
203b49cda9fSStefano Zampini     ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
204b49cda9fSStefano Zampini     ierr = MatSetType(B,MATSEQDENSE);CHKERRQ(ierr);
205b49cda9fSStefano Zampini     ierr = MatSeqDenseSetPreallocation(B,NULL);CHKERRQ(ierr);
206b49cda9fSStefano Zampini     b    = (Mat_SeqDense*)(B->data);
207a13144ffSStefano Zampini   } else {
208a13144ffSStefano Zampini     b    = (Mat_SeqDense*)((*newmat)->data);
209580bdb30SBarry Smith     ierr = PetscArrayzero(b->v,m*n);CHKERRQ(ierr);
210a13144ffSStefano Zampini   }
211b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
212b49cda9fSStefano Zampini     PetscInt j;
213b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
214b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
215b49cda9fSStefano Zampini       aj++;
216b49cda9fSStefano Zampini       av++;
217b49cda9fSStefano Zampini     }
218b49cda9fSStefano Zampini     ai++;
219b49cda9fSStefano Zampini   }
220b49cda9fSStefano Zampini 
221511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
222a13144ffSStefano Zampini     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
223a13144ffSStefano Zampini     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22428be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
225b49cda9fSStefano Zampini   } else {
226a13144ffSStefano Zampini     if (B) *newmat = B;
227a13144ffSStefano Zampini     ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
228a13144ffSStefano Zampini     ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
229b49cda9fSStefano Zampini   }
230b49cda9fSStefano Zampini   PetscFunctionReturn(0);
231b49cda9fSStefano Zampini }
232b49cda9fSStefano Zampini 
233cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
2346a63e612SBarry Smith {
2356a63e612SBarry Smith   Mat            B;
2366a63e612SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2376a63e612SBarry Smith   PetscErrorCode ierr;
2389399e1b8SMatthew G. Knepley   PetscInt       i, j;
2399399e1b8SMatthew G. Knepley   PetscInt       *rows, *nnz;
2409399e1b8SMatthew G. Knepley   MatScalar      *aa = a->v, *vals;
2416a63e612SBarry Smith 
2426a63e612SBarry Smith   PetscFunctionBegin;
243ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
2446a63e612SBarry Smith   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
2456a63e612SBarry Smith   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
2469399e1b8SMatthew G. Knepley   ierr = PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals);CHKERRQ(ierr);
2479399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2489399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) ++nnz[i];
2496a63e612SBarry Smith     aa += a->lda;
2506a63e612SBarry Smith   }
2519399e1b8SMatthew G. Knepley   ierr = MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz);CHKERRQ(ierr);
2529399e1b8SMatthew G. Knepley   aa = a->v;
2539399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2549399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2559399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) {rows[numRows] = i; vals[numRows++] = aa[i];}
2569399e1b8SMatthew G. Knepley     ierr = MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr);
2579399e1b8SMatthew G. Knepley     aa  += a->lda;
2589399e1b8SMatthew G. Knepley   }
2599399e1b8SMatthew G. Knepley   ierr = PetscFree3(rows,nnz,vals);CHKERRQ(ierr);
2606a63e612SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2616a63e612SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2626a63e612SBarry Smith 
263511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
26428be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
2656a63e612SBarry Smith   } else {
2666a63e612SBarry Smith     *newmat = B;
2676a63e612SBarry Smith   }
2686a63e612SBarry Smith   PetscFunctionReturn(0);
2696a63e612SBarry Smith }
2706a63e612SBarry Smith 
271e0877f53SBarry Smith static PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
2721987afe7SBarry Smith {
2731987afe7SBarry Smith   Mat_SeqDense   *x     = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
274f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
27513f74950SBarry Smith   PetscInt       j;
2760805154bSBarry Smith   PetscBLASInt   N,m,ldax,lday,one = 1;
277efee365bSSatish Balay   PetscErrorCode ierr;
2783a40ed3dSBarry Smith 
2793a40ed3dSBarry Smith   PetscFunctionBegin;
280c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n*X->cmap->n,&N);CHKERRQ(ierr);
281c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n,&m);CHKERRQ(ierr);
282c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->lda,&ldax);CHKERRQ(ierr);
283c5df96a5SBarry Smith   ierr = PetscBLASIntCast(y->lda,&lday);CHKERRQ(ierr);
284a5ce6ee0Svictorle   if (ldax>m || lday>m) {
285d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
2868b83055fSJed Brown       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&oalpha,x->v+j*ldax,&one,y->v+j*lday,&one));
287a5ce6ee0Svictorle     }
288a5ce6ee0Svictorle   } else {
2898b83055fSJed Brown     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&oalpha,x->v,&one,y->v,&one));
290a5ce6ee0Svictorle   }
291a3fa217bSJose E. Roman   ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr);
2920450473dSBarry Smith   ierr = PetscLogFlops(PetscMax(2*N-1,0));CHKERRQ(ierr);
2933a40ed3dSBarry Smith   PetscFunctionReturn(0);
2941987afe7SBarry Smith }
2951987afe7SBarry Smith 
296e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
297289bc588SBarry Smith {
298d0f46423SBarry Smith   PetscInt N = A->rmap->n*A->cmap->n;
2993a40ed3dSBarry Smith 
3003a40ed3dSBarry Smith   PetscFunctionBegin;
3014e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
3024e220ebcSLois Curfman McInnes   info->nz_allocated      = (double)N;
3036de62eeeSBarry Smith   info->nz_used           = (double)N;
3046de62eeeSBarry Smith   info->nz_unneeded       = (double)0;
3054e220ebcSLois Curfman McInnes   info->assemblies        = (double)A->num_ass;
3064e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3077adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3084e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3094e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3104e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3113a40ed3dSBarry Smith   PetscFunctionReturn(0);
312289bc588SBarry Smith }
313289bc588SBarry Smith 
314e0877f53SBarry Smith static PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
31580cd9d93SLois Curfman McInnes {
316273d9f13SBarry Smith   Mat_SeqDense   *a     = (Mat_SeqDense*)A->data;
317f4df32b1SMatthew Knepley   PetscScalar    oalpha = alpha;
318efee365bSSatish Balay   PetscErrorCode ierr;
319c5df96a5SBarry Smith   PetscBLASInt   one = 1,j,nz,lda;
32080cd9d93SLois Curfman McInnes 
3213a40ed3dSBarry Smith   PetscFunctionBegin;
322c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->lda,&lda);CHKERRQ(ierr);
323d0f46423SBarry Smith   if (lda>A->rmap->n) {
324c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n,&nz);CHKERRQ(ierr);
325d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
3268b83055fSJed Brown       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&oalpha,a->v+j*lda,&one));
327a5ce6ee0Svictorle     }
328a5ce6ee0Svictorle   } else {
329c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz);CHKERRQ(ierr);
3308b83055fSJed Brown     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&oalpha,a->v,&one));
331a5ce6ee0Svictorle   }
332efee365bSSatish Balay   ierr = PetscLogFlops(nz);CHKERRQ(ierr);
3333a40ed3dSBarry Smith   PetscFunctionReturn(0);
33480cd9d93SLois Curfman McInnes }
33580cd9d93SLois Curfman McInnes 
336e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3371cbb95d3SBarry Smith {
3381cbb95d3SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
339d0f46423SBarry Smith   PetscInt     i,j,m = A->rmap->n,N;
3401cbb95d3SBarry Smith   PetscScalar  *v = a->v;
3411cbb95d3SBarry Smith 
3421cbb95d3SBarry Smith   PetscFunctionBegin;
3431cbb95d3SBarry Smith   *fl = PETSC_FALSE;
344d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3451cbb95d3SBarry Smith   N = a->lda;
3461cbb95d3SBarry Smith 
3471cbb95d3SBarry Smith   for (i=0; i<m; i++) {
3481cbb95d3SBarry Smith     for (j=i+1; j<m; j++) {
3491cbb95d3SBarry Smith       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) PetscFunctionReturn(0);
3501cbb95d3SBarry Smith     }
3511cbb95d3SBarry Smith   }
3521cbb95d3SBarry Smith   *fl = PETSC_TRUE;
3531cbb95d3SBarry Smith   PetscFunctionReturn(0);
3541cbb95d3SBarry Smith }
3551cbb95d3SBarry Smith 
356e0877f53SBarry Smith static PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
357b24902e0SBarry Smith {
358b24902e0SBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data,*l;
359b24902e0SBarry Smith   PetscErrorCode ierr;
360b24902e0SBarry Smith   PetscInt       lda = (PetscInt)mat->lda,j,m;
361b24902e0SBarry Smith 
362b24902e0SBarry Smith   PetscFunctionBegin;
363aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr);
364aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr);
3650298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr);
366b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
367b24902e0SBarry Smith     l = (Mat_SeqDense*)newi->data;
368d0f46423SBarry Smith     if (lda>A->rmap->n) {
369d0f46423SBarry Smith       m = A->rmap->n;
370d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
371580bdb30SBarry Smith         ierr = PetscArraycpy(l->v+j*m,mat->v+j*lda,m);CHKERRQ(ierr);
372b24902e0SBarry Smith       }
373b24902e0SBarry Smith     } else {
374580bdb30SBarry Smith       ierr = PetscArraycpy(l->v,mat->v,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
375b24902e0SBarry Smith     }
376b24902e0SBarry Smith   }
377b24902e0SBarry Smith   newi->assembled = PETSC_TRUE;
378b24902e0SBarry Smith   PetscFunctionReturn(0);
379b24902e0SBarry Smith }
380b24902e0SBarry Smith 
381e0877f53SBarry Smith static PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
38202cad45dSBarry Smith {
3836849ba73SBarry Smith   PetscErrorCode ierr;
38402cad45dSBarry Smith 
3853a40ed3dSBarry Smith   PetscFunctionBegin;
386ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr);
387d0f46423SBarry Smith   ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
3885c9eb25fSBarry Smith   ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
389719d5645SBarry Smith   ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr);
390b24902e0SBarry Smith   PetscFunctionReturn(0);
391b24902e0SBarry Smith }
392b24902e0SBarry Smith 
3936ee01492SSatish Balay 
394e0877f53SBarry Smith static PetscErrorCode MatLUFactor_SeqDense(Mat,IS,IS,const MatFactorInfo*);
395719d5645SBarry Smith 
396e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
397289bc588SBarry Smith {
3984482741eSBarry Smith   MatFactorInfo  info;
399a093e273SMatthew Knepley   PetscErrorCode ierr;
4003a40ed3dSBarry Smith 
4013a40ed3dSBarry Smith   PetscFunctionBegin;
402c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
403719d5645SBarry Smith   ierr = MatLUFactor_SeqDense(fact,0,0,&info);CHKERRQ(ierr);
4043a40ed3dSBarry Smith   PetscFunctionReturn(0);
405289bc588SBarry Smith }
4066ee01492SSatish Balay 
407e0877f53SBarry Smith static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy)
408289bc588SBarry Smith {
409c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
4106849ba73SBarry Smith   PetscErrorCode    ierr;
411f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
412f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
413c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
41467e560aaSBarry Smith 
4153a40ed3dSBarry Smith   PetscFunctionBegin;
416c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
417f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4181ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
419580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
420d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_LU) {
421ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
422e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
423ae7cfcebSSatish Balay #else
42400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4258b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
42600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
427e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
428ae7cfcebSSatish Balay #endif
429d5f3da31SBarry Smith   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
430ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
431e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
432ae7cfcebSSatish Balay #else
433a49dc2a2SStefano Zampini     if (A->spd) {
43400121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4358b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
43600121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
437e32f2f54SBarry Smith       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
438a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
439a49dc2a2SStefano Zampini     } else if (A->hermitian) {
44000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
441a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
44200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
443a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
444a49dc2a2SStefano Zampini #endif
445a49dc2a2SStefano Zampini     } else { /* symmetric case */
44600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
447a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
44800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
449a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
450a49dc2a2SStefano Zampini     }
451ae7cfcebSSatish Balay #endif
4522205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
453f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4541ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
455dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
4563a40ed3dSBarry Smith   PetscFunctionReturn(0);
457289bc588SBarry Smith }
4586ee01492SSatish Balay 
459e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X)
46085e2c93fSHong Zhang {
46185e2c93fSHong Zhang   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
46285e2c93fSHong Zhang   PetscErrorCode    ierr;
4631683a169SBarry Smith   const PetscScalar *b;
4641683a169SBarry Smith   PetscScalar       *x;
465efb80c78SLisandro Dalcin   PetscInt          n;
466783b601eSJed Brown   PetscBLASInt      nrhs,info,m;
467bda8bf91SBarry Smith   PetscBool         flg;
46885e2c93fSHong Zhang 
46985e2c93fSHong Zhang   PetscFunctionBegin;
470c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
4710298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
472ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
4730298fd71SBarry Smith   ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr);
474ce94432eSBarry Smith   if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
475bda8bf91SBarry Smith 
4760298fd71SBarry Smith   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
477c5df96a5SBarry Smith   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
4781683a169SBarry Smith   ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
4798c778c55SBarry Smith   ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr);
48085e2c93fSHong Zhang 
481580bdb30SBarry Smith   ierr = PetscArraycpy(x,b,m*nrhs);CHKERRQ(ierr);
48285e2c93fSHong Zhang 
48385e2c93fSHong Zhang   if (A->factortype == MAT_FACTOR_LU) {
48485e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_GETRS)
48585e2c93fSHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
48685e2c93fSHong Zhang #else
48700121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4888b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
48900121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
49085e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
49185e2c93fSHong Zhang #endif
49285e2c93fSHong Zhang   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
49385e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_POTRS)
49485e2c93fSHong Zhang     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
49585e2c93fSHong Zhang #else
496a49dc2a2SStefano Zampini     if (A->spd) {
49700121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4988b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
49900121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
50085e2c93fSHong Zhang       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
501a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
502a49dc2a2SStefano Zampini     } else if (A->hermitian) {
50300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
504a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
50500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
506a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
507a49dc2a2SStefano Zampini #endif
508a49dc2a2SStefano Zampini     } else { /* symmetric case */
50900121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
510a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
51100121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
512a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
513a49dc2a2SStefano Zampini     }
51485e2c93fSHong Zhang #endif
5152205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
51685e2c93fSHong Zhang 
5171683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
5188c778c55SBarry Smith   ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr);
51985e2c93fSHong Zhang   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
52085e2c93fSHong Zhang   PetscFunctionReturn(0);
52185e2c93fSHong Zhang }
52285e2c93fSHong Zhang 
52300121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
52400121966SStefano Zampini 
525e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
526da3a660dSBarry Smith {
527c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
528dfbe8321SBarry Smith   PetscErrorCode    ierr;
529f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
530f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
531c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
53267e560aaSBarry Smith 
5333a40ed3dSBarry Smith   PetscFunctionBegin;
534c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
535f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5361ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
537580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
5388208b9aeSStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
539ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
540e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable.");
541ae7cfcebSSatish Balay #else
54200121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5438b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
54400121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
545e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve");
546ae7cfcebSSatish Balay #endif
5478208b9aeSStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
548ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
549e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable.");
550ae7cfcebSSatish Balay #else
551a49dc2a2SStefano Zampini     if (A->spd) {
55200121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
55300121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
55400121966SStefano Zampini #endif
55500121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5568b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
55700121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
55800121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
55900121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
56000121966SStefano Zampini #endif
561a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
562a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
563a49dc2a2SStefano Zampini     } else if (A->hermitian) {
56400121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
56500121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
56600121966SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
56700121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
56800121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
569ae7cfcebSSatish Balay #endif
570a49dc2a2SStefano Zampini     } else { /* symmetric case */
57100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
572a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
57300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
574a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
575da3a660dSBarry Smith     }
576a49dc2a2SStefano Zampini #endif
577a49dc2a2SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
578f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5791ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
580dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
5813a40ed3dSBarry Smith   PetscFunctionReturn(0);
582da3a660dSBarry Smith }
5836ee01492SSatish Balay 
584e0877f53SBarry Smith static PetscErrorCode MatSolveAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
585da3a660dSBarry Smith {
586dfbe8321SBarry Smith   PetscErrorCode    ierr;
587f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
588f1ceaac6SMatthew G. Knepley   PetscScalar       *y,sone = 1.0;
589da3a660dSBarry Smith   Vec               tmp = 0;
59067e560aaSBarry Smith 
5913a40ed3dSBarry Smith   PetscFunctionBegin;
592f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5931ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
594d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
595da3a660dSBarry Smith   if (yy == zz) {
59678b31e54SBarry Smith     ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr);
5973bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)tmp);CHKERRQ(ierr);
59878b31e54SBarry Smith     ierr = VecCopy(yy,tmp);CHKERRQ(ierr);
599da3a660dSBarry Smith   }
6008208b9aeSStefano Zampini   ierr = MatSolve_SeqDense(A,xx,yy);CHKERRQ(ierr);
6016bf464f9SBarry Smith   if (tmp) {
6026bf464f9SBarry Smith     ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr);
6036bf464f9SBarry Smith     ierr = VecDestroy(&tmp);CHKERRQ(ierr);
6046bf464f9SBarry Smith   } else {
6056bf464f9SBarry Smith     ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr);
6066bf464f9SBarry Smith   }
607f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
6081ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
6098208b9aeSStefano Zampini   ierr = PetscLogFlops(A->cmap->n);CHKERRQ(ierr);
6103a40ed3dSBarry Smith   PetscFunctionReturn(0);
611da3a660dSBarry Smith }
61267e560aaSBarry Smith 
613e0877f53SBarry Smith static PetscErrorCode MatSolveTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
614da3a660dSBarry Smith {
6156849ba73SBarry Smith   PetscErrorCode    ierr;
616f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
617f1ceaac6SMatthew G. Knepley   PetscScalar       *y,sone = 1.0;
61889ae1891SBarry Smith   Vec               tmp = NULL;
61967e560aaSBarry Smith 
6203a40ed3dSBarry Smith   PetscFunctionBegin;
621d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
622f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
6231ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
624da3a660dSBarry Smith   if (yy == zz) {
62578b31e54SBarry Smith     ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr);
6263bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)tmp);CHKERRQ(ierr);
62778b31e54SBarry Smith     ierr = VecCopy(yy,tmp);CHKERRQ(ierr);
628da3a660dSBarry Smith   }
6298208b9aeSStefano Zampini   ierr = MatSolveTranspose_SeqDense(A,xx,yy);CHKERRQ(ierr);
63090f02eecSBarry Smith   if (tmp) {
6312dcb1b2aSMatthew Knepley     ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr);
6326bf464f9SBarry Smith     ierr = VecDestroy(&tmp);CHKERRQ(ierr);
6333a40ed3dSBarry Smith   } else {
6342dcb1b2aSMatthew Knepley     ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr);
63590f02eecSBarry Smith   }
636f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
6371ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
6388208b9aeSStefano Zampini   ierr = PetscLogFlops(A->cmap->n);CHKERRQ(ierr);
6393a40ed3dSBarry Smith   PetscFunctionReturn(0);
640da3a660dSBarry Smith }
641db4efbfdSBarry Smith 
642db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
643db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
644db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
645e0877f53SBarry Smith static PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
646db4efbfdSBarry Smith {
647db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_GETRF)
648db4efbfdSBarry Smith   PetscFunctionBegin;
649e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRF - Lapack routine is unavailable.");
650db4efbfdSBarry Smith #else
651db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
652db4efbfdSBarry Smith   PetscErrorCode ierr;
653db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
654db4efbfdSBarry Smith 
655db4efbfdSBarry Smith   PetscFunctionBegin;
656c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
657c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
658db4efbfdSBarry Smith   if (!mat->pivots) {
6598208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
6603bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
661db4efbfdSBarry Smith   }
662db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
6638e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6648b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
6658e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
6668e57ea43SSatish Balay 
667e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
668e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
6698208b9aeSStefano Zampini 
670db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6718208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
672db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
673db4efbfdSBarry Smith   A->ops->solveadd          = MatSolveAdd_SeqDense;
674db4efbfdSBarry Smith   A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
675d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
676db4efbfdSBarry Smith 
677f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
678f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
679f6224b95SHong Zhang 
680dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
681db4efbfdSBarry Smith #endif
682db4efbfdSBarry Smith   PetscFunctionReturn(0);
683db4efbfdSBarry Smith }
684db4efbfdSBarry Smith 
685a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
686e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
687db4efbfdSBarry Smith {
688db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_POTRF)
689db4efbfdSBarry Smith   PetscFunctionBegin;
690e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF - Lapack routine is unavailable.");
691db4efbfdSBarry Smith #else
692db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
693db4efbfdSBarry Smith   PetscErrorCode ierr;
694c5df96a5SBarry Smith   PetscBLASInt   info,n;
695db4efbfdSBarry Smith 
696db4efbfdSBarry Smith   PetscFunctionBegin;
697c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
698db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
699a49dc2a2SStefano Zampini   if (A->spd) {
70000121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
7018b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
70200121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
703a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
704a49dc2a2SStefano Zampini   } else if (A->hermitian) {
705a49dc2a2SStefano Zampini     if (!mat->pivots) {
706a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
707a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
708a49dc2a2SStefano Zampini     }
709a49dc2a2SStefano Zampini     if (!mat->fwork) {
710a49dc2a2SStefano Zampini       PetscScalar dummy;
711a49dc2a2SStefano Zampini 
712a49dc2a2SStefano Zampini       mat->lfwork = -1;
71300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
714a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
71500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
716a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
717a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
718a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
719a49dc2a2SStefano Zampini     }
72000121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
721a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
72200121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
723a49dc2a2SStefano Zampini #endif
724a49dc2a2SStefano Zampini   } else { /* symmetric case */
725a49dc2a2SStefano Zampini     if (!mat->pivots) {
726a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
727a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
728a49dc2a2SStefano Zampini     }
729a49dc2a2SStefano Zampini     if (!mat->fwork) {
730a49dc2a2SStefano Zampini       PetscScalar dummy;
731a49dc2a2SStefano Zampini 
732a49dc2a2SStefano Zampini       mat->lfwork = -1;
73300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
734a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
73500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
736a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
737a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
738a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
739a49dc2a2SStefano Zampini     }
74000121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
741a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
74200121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
743a49dc2a2SStefano Zampini   }
744e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
7458208b9aeSStefano Zampini 
746db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
7478208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
748db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
749db4efbfdSBarry Smith   A->ops->solveadd          = MatSolveAdd_SeqDense;
750db4efbfdSBarry Smith   A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
751d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
7522205254eSKarl Rupp 
753f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
754f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
755f6224b95SHong Zhang 
756eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
757db4efbfdSBarry Smith #endif
758db4efbfdSBarry Smith   PetscFunctionReturn(0);
759db4efbfdSBarry Smith }
760db4efbfdSBarry Smith 
761db4efbfdSBarry Smith 
7620481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
763db4efbfdSBarry Smith {
764db4efbfdSBarry Smith   PetscErrorCode ierr;
765db4efbfdSBarry Smith   MatFactorInfo  info;
766db4efbfdSBarry Smith 
767db4efbfdSBarry Smith   PetscFunctionBegin;
768db4efbfdSBarry Smith   info.fill = 1.0;
7692205254eSKarl Rupp 
770c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
771719d5645SBarry Smith   ierr = MatCholeskyFactor_SeqDense(fact,0,&info);CHKERRQ(ierr);
772db4efbfdSBarry Smith   PetscFunctionReturn(0);
773db4efbfdSBarry Smith }
774db4efbfdSBarry Smith 
775e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
776db4efbfdSBarry Smith {
777db4efbfdSBarry Smith   PetscFunctionBegin;
778c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
7791bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
780719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
781bd443b22SStefano Zampini   fact->ops->solve                 = MatSolve_SeqDense;
782bd443b22SStefano Zampini   fact->ops->matsolve              = MatMatSolve_SeqDense;
783bd443b22SStefano Zampini   fact->ops->solvetranspose        = MatSolveTranspose_SeqDense;
784bd443b22SStefano Zampini   fact->ops->solveadd              = MatSolveAdd_SeqDense;
785bd443b22SStefano Zampini   fact->ops->solvetransposeadd     = MatSolveTransposeAdd_SeqDense;
786db4efbfdSBarry Smith   PetscFunctionReturn(0);
787db4efbfdSBarry Smith }
788db4efbfdSBarry Smith 
789e0877f53SBarry Smith static PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
790db4efbfdSBarry Smith {
791db4efbfdSBarry Smith   PetscFunctionBegin;
792b66fe19dSMatthew G Knepley   fact->preallocated           = PETSC_TRUE;
793c3ef05f6SHong Zhang   fact->assembled              = PETSC_TRUE;
794719d5645SBarry Smith   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
795bd443b22SStefano Zampini   fact->ops->solve             = MatSolve_SeqDense;
796bd443b22SStefano Zampini   fact->ops->matsolve          = MatMatSolve_SeqDense;
797bd443b22SStefano Zampini   fact->ops->solvetranspose    = MatSolveTranspose_SeqDense;
798bd443b22SStefano Zampini   fact->ops->solveadd          = MatSolveAdd_SeqDense;
799bd443b22SStefano Zampini   fact->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense;
800db4efbfdSBarry Smith   PetscFunctionReturn(0);
801db4efbfdSBarry Smith }
802db4efbfdSBarry Smith 
803cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
804db4efbfdSBarry Smith {
805db4efbfdSBarry Smith   PetscErrorCode ierr;
806db4efbfdSBarry Smith 
807db4efbfdSBarry Smith   PetscFunctionBegin;
808ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
809db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
810db4efbfdSBarry Smith   ierr = MatSetType(*fact,((PetscObject)A)->type_name);CHKERRQ(ierr);
811db4efbfdSBarry Smith   if (ftype == MAT_FACTOR_LU) {
812db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
813db4efbfdSBarry Smith   } else {
814db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
815db4efbfdSBarry Smith   }
816d5f3da31SBarry Smith   (*fact)->factortype = ftype;
81700c67f3bSHong Zhang 
81800c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
81900c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
820db4efbfdSBarry Smith   PetscFunctionReturn(0);
821db4efbfdSBarry Smith }
822db4efbfdSBarry Smith 
823289bc588SBarry Smith /* ------------------------------------------------------------------*/
824e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
825289bc588SBarry Smith {
826c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
827d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
828d9ca1df4SBarry Smith   const PetscScalar *b;
829dfbe8321SBarry Smith   PetscErrorCode    ierr;
830d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
831c5df96a5SBarry Smith   PetscBLASInt      o = 1,bm;
832289bc588SBarry Smith 
8333a40ed3dSBarry Smith   PetscFunctionBegin;
834422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
835c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
836289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
8373bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
8382dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
839289bc588SBarry Smith   }
8401ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
841d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
842b965ef7fSBarry Smith   its  = its*lits;
843e32f2f54SBarry 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);
844289bc588SBarry Smith   while (its--) {
845fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
846289bc588SBarry Smith       for (i=0; i<m; i++) {
8473bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
84855a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
849289bc588SBarry Smith       }
850289bc588SBarry Smith     }
851fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
852289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
8533bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
85455a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
855289bc588SBarry Smith       }
856289bc588SBarry Smith     }
857289bc588SBarry Smith   }
858d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
8591ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
8603a40ed3dSBarry Smith   PetscFunctionReturn(0);
861289bc588SBarry Smith }
862289bc588SBarry Smith 
863289bc588SBarry Smith /* -----------------------------------------------------------------*/
864cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
865289bc588SBarry Smith {
866c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
867d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
868d9ca1df4SBarry Smith   PetscScalar       *y;
869dfbe8321SBarry Smith   PetscErrorCode    ierr;
8700805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
871ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
8723a40ed3dSBarry Smith 
8733a40ed3dSBarry Smith   PetscFunctionBegin;
874c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
875c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
876d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8771ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8785ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8795ac36cfcSBarry Smith     PetscBLASInt i;
8805ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
8815ac36cfcSBarry Smith   } else {
8828b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
8835ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
8845ac36cfcSBarry Smith   }
885d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8861ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
8873a40ed3dSBarry Smith   PetscFunctionReturn(0);
888289bc588SBarry Smith }
889800995b7SMatthew Knepley 
890cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
891289bc588SBarry Smith {
892c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
893d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
894dfbe8321SBarry Smith   PetscErrorCode    ierr;
8950805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
896d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
8973a40ed3dSBarry Smith 
8983a40ed3dSBarry Smith   PetscFunctionBegin;
899c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
900c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
901d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
9021ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9035ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
9045ac36cfcSBarry Smith     PetscBLASInt i;
9055ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
9065ac36cfcSBarry Smith   } else {
9078b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
9085ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
9095ac36cfcSBarry Smith   }
910d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
9111ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
9123a40ed3dSBarry Smith   PetscFunctionReturn(0);
913289bc588SBarry Smith }
9146ee01492SSatish Balay 
915cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
916289bc588SBarry Smith {
917c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
918d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
919d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
920dfbe8321SBarry Smith   PetscErrorCode    ierr;
9210805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
9223a40ed3dSBarry Smith 
9233a40ed3dSBarry Smith   PetscFunctionBegin;
924c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
925c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
926d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
927600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
928d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
9291ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9308b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
931d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
9321ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
933dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
9343a40ed3dSBarry Smith   PetscFunctionReturn(0);
935289bc588SBarry Smith }
9366ee01492SSatish Balay 
937e0877f53SBarry Smith static PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
938289bc588SBarry Smith {
939c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
940d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
941d9ca1df4SBarry Smith   PetscScalar       *y;
942dfbe8321SBarry Smith   PetscErrorCode    ierr;
9430805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
94487828ca2SBarry Smith   PetscScalar       _DOne=1.0;
9453a40ed3dSBarry Smith 
9463a40ed3dSBarry Smith   PetscFunctionBegin;
947c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
948c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
949d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
950600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
951d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
9521ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
9538b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
954d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
9551ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
956dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
9573a40ed3dSBarry Smith   PetscFunctionReturn(0);
958289bc588SBarry Smith }
959289bc588SBarry Smith 
960289bc588SBarry Smith /* -----------------------------------------------------------------*/
961e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
962289bc588SBarry Smith {
963c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
96487828ca2SBarry Smith   PetscScalar    *v;
9656849ba73SBarry Smith   PetscErrorCode ierr;
96613f74950SBarry Smith   PetscInt       i;
96767e560aaSBarry Smith 
9683a40ed3dSBarry Smith   PetscFunctionBegin;
969d0f46423SBarry Smith   *ncols = A->cmap->n;
970289bc588SBarry Smith   if (cols) {
971854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
972d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
973289bc588SBarry Smith   }
974289bc588SBarry Smith   if (vals) {
975854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
976289bc588SBarry Smith     v    = mat->v + row;
977d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
978289bc588SBarry Smith   }
9793a40ed3dSBarry Smith   PetscFunctionReturn(0);
980289bc588SBarry Smith }
9816ee01492SSatish Balay 
982e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
983289bc588SBarry Smith {
984dfbe8321SBarry Smith   PetscErrorCode ierr;
9856e111a19SKarl Rupp 
986606d414cSSatish Balay   PetscFunctionBegin;
987606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
988606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
9893a40ed3dSBarry Smith   PetscFunctionReturn(0);
990289bc588SBarry Smith }
991289bc588SBarry Smith /* ----------------------------------------------------------------*/
992e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
993289bc588SBarry Smith {
994c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
99513f74950SBarry Smith   PetscInt     i,j,idx=0;
996d6dfbf8fSBarry Smith 
9973a40ed3dSBarry Smith   PetscFunctionBegin;
998289bc588SBarry Smith   if (!mat->roworiented) {
999dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1000289bc588SBarry Smith       for (j=0; j<n; j++) {
1001cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
10022515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1003e32f2f54SBarry 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);
100458804f6dSBarry Smith #endif
1005289bc588SBarry Smith         for (i=0; i<m; i++) {
1006cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
10072515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1008e32f2f54SBarry 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);
100958804f6dSBarry Smith #endif
1010cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1011289bc588SBarry Smith         }
1012289bc588SBarry Smith       }
10133a40ed3dSBarry Smith     } else {
1014289bc588SBarry Smith       for (j=0; j<n; j++) {
1015cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
10162515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1017e32f2f54SBarry 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);
101858804f6dSBarry Smith #endif
1019289bc588SBarry Smith         for (i=0; i<m; i++) {
1020cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
10212515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1022e32f2f54SBarry 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);
102358804f6dSBarry Smith #endif
1024cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1025289bc588SBarry Smith         }
1026289bc588SBarry Smith       }
1027289bc588SBarry Smith     }
10283a40ed3dSBarry Smith   } else {
1029dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1030e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
1031cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
10322515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1033e32f2f54SBarry 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);
103458804f6dSBarry Smith #endif
1035e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
1036cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
10372515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1038e32f2f54SBarry 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);
103958804f6dSBarry Smith #endif
1040cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1041e8d4e0b9SBarry Smith         }
1042e8d4e0b9SBarry Smith       }
10433a40ed3dSBarry Smith     } else {
1044289bc588SBarry Smith       for (i=0; i<m; i++) {
1045cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
10462515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1047e32f2f54SBarry 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);
104858804f6dSBarry Smith #endif
1049289bc588SBarry Smith         for (j=0; j<n; j++) {
1050cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
10512515c552SBarry Smith #if defined(PETSC_USE_DEBUG)
1052e32f2f54SBarry 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);
105358804f6dSBarry Smith #endif
1054cddbea37SSatish Balay           mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1055289bc588SBarry Smith         }
1056289bc588SBarry Smith       }
1057289bc588SBarry Smith     }
1058e8d4e0b9SBarry Smith   }
10593a40ed3dSBarry Smith   PetscFunctionReturn(0);
1060289bc588SBarry Smith }
1061e8d4e0b9SBarry Smith 
1062e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1063ae80bb75SLois Curfman McInnes {
1064ae80bb75SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
106513f74950SBarry Smith   PetscInt     i,j;
1066ae80bb75SLois Curfman McInnes 
10673a40ed3dSBarry Smith   PetscFunctionBegin;
1068ae80bb75SLois Curfman McInnes   /* row-oriented output */
1069ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
107097e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1071e32f2f54SBarry 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);
1072ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
10736f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1074e32f2f54SBarry 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);
107597e567efSBarry Smith       *v++ = mat->v[indexn[j]*mat->lda + indexm[i]];
1076ae80bb75SLois Curfman McInnes     }
1077ae80bb75SLois Curfman McInnes   }
10783a40ed3dSBarry Smith   PetscFunctionReturn(0);
1079ae80bb75SLois Curfman McInnes }
1080ae80bb75SLois Curfman McInnes 
1081289bc588SBarry Smith /* -----------------------------------------------------------------*/
1082289bc588SBarry Smith 
1083eb91f321SVaclav Hapla static PetscErrorCode MatLoad_SeqDense_Binary(Mat newmat,PetscViewer viewer)
1084aabbc4fbSShri Abhyankar {
1085aabbc4fbSShri Abhyankar   Mat_SeqDense   *a;
1086aabbc4fbSShri Abhyankar   PetscErrorCode ierr;
1087aabbc4fbSShri Abhyankar   PetscInt       *scols,i,j,nz,header[4];
1088aabbc4fbSShri Abhyankar   int            fd;
1089aabbc4fbSShri Abhyankar   PetscMPIInt    size;
1090aabbc4fbSShri Abhyankar   PetscInt       *rowlengths = 0,M,N,*cols,grows,gcols;
1091aabbc4fbSShri Abhyankar   PetscScalar    *vals,*svals,*v,*w;
1092ce94432eSBarry Smith   MPI_Comm       comm;
1093aabbc4fbSShri Abhyankar 
1094aabbc4fbSShri Abhyankar   PetscFunctionBegin;
1095ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
1096aabbc4fbSShri Abhyankar   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1097aabbc4fbSShri Abhyankar   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"view must have one processor");
1098aabbc4fbSShri Abhyankar   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
10999860990eSLisandro Dalcin   ierr = PetscBinaryRead(fd,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
1100aabbc4fbSShri Abhyankar   if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not matrix object");
1101aabbc4fbSShri Abhyankar   M = header[1]; N = header[2]; nz = header[3];
1102aabbc4fbSShri Abhyankar 
1103aabbc4fbSShri Abhyankar   /* set global size if not set already*/
1104aabbc4fbSShri Abhyankar   if (newmat->rmap->n < 0 && newmat->rmap->N < 0 && newmat->cmap->n < 0 && newmat->cmap->N < 0) {
1105aabbc4fbSShri Abhyankar     ierr = MatSetSizes(newmat,M,N,M,N);CHKERRQ(ierr);
1106aabbc4fbSShri Abhyankar   } else {
1107aabbc4fbSShri Abhyankar     /* if sizes and type are already set, check if the vector global sizes are correct */
1108aabbc4fbSShri Abhyankar     ierr = MatGetSize(newmat,&grows,&gcols);CHKERRQ(ierr);
1109aabbc4fbSShri 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);
1110aabbc4fbSShri Abhyankar   }
1111e6324fbbSBarry Smith   a = (Mat_SeqDense*)newmat->data;
1112e6324fbbSBarry Smith   if (!a->user_alloc) {
11130298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1114e6324fbbSBarry Smith   }
1115aabbc4fbSShri Abhyankar 
1116aabbc4fbSShri Abhyankar   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense */
1117aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
1118aabbc4fbSShri Abhyankar     v = a->v;
1119aabbc4fbSShri Abhyankar     /* Allocate some temp space to read in the values and then flip them
1120aabbc4fbSShri Abhyankar        from row major to column major */
1121854ce69bSBarry Smith     ierr = PetscMalloc1(M*N > 0 ? M*N : 1,&w);CHKERRQ(ierr);
1122aabbc4fbSShri Abhyankar     /* read in nonzero values */
11239860990eSLisandro Dalcin     ierr = PetscBinaryRead(fd,w,M*N,NULL,PETSC_SCALAR);CHKERRQ(ierr);
1124aabbc4fbSShri Abhyankar     /* now flip the values and store them in the matrix*/
1125aabbc4fbSShri Abhyankar     for (j=0; j<N; j++) {
1126aabbc4fbSShri Abhyankar       for (i=0; i<M; i++) {
1127aabbc4fbSShri Abhyankar         *v++ =w[i*N+j];
1128aabbc4fbSShri Abhyankar       }
1129aabbc4fbSShri Abhyankar     }
1130aabbc4fbSShri Abhyankar     ierr = PetscFree(w);CHKERRQ(ierr);
1131aabbc4fbSShri Abhyankar   } else {
1132aabbc4fbSShri Abhyankar     /* read row lengths */
1133854ce69bSBarry Smith     ierr = PetscMalloc1(M+1,&rowlengths);CHKERRQ(ierr);
11349860990eSLisandro Dalcin     ierr = PetscBinaryRead(fd,rowlengths,M,NULL,PETSC_INT);CHKERRQ(ierr);
1135aabbc4fbSShri Abhyankar 
1136aabbc4fbSShri Abhyankar     a = (Mat_SeqDense*)newmat->data;
1137aabbc4fbSShri Abhyankar     v = a->v;
1138aabbc4fbSShri Abhyankar 
1139aabbc4fbSShri Abhyankar     /* read column indices and nonzeros */
1140854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&scols);CHKERRQ(ierr);
1141aabbc4fbSShri Abhyankar     cols = scols;
11429860990eSLisandro Dalcin     ierr = PetscBinaryRead(fd,cols,nz,NULL,PETSC_INT);CHKERRQ(ierr);
1143854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&svals);CHKERRQ(ierr);
1144aabbc4fbSShri Abhyankar     vals = svals;
11459860990eSLisandro Dalcin     ierr = PetscBinaryRead(fd,vals,nz,NULL,PETSC_SCALAR);CHKERRQ(ierr);
1146aabbc4fbSShri Abhyankar 
1147aabbc4fbSShri Abhyankar     /* insert into matrix */
1148aabbc4fbSShri Abhyankar     for (i=0; i<M; i++) {
1149aabbc4fbSShri Abhyankar       for (j=0; j<rowlengths[i]; j++) v[i+M*scols[j]] = svals[j];
1150aabbc4fbSShri Abhyankar       svals += rowlengths[i]; scols += rowlengths[i];
1151aabbc4fbSShri Abhyankar     }
1152aabbc4fbSShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1153aabbc4fbSShri Abhyankar     ierr = PetscFree(cols);CHKERRQ(ierr);
1154aabbc4fbSShri Abhyankar     ierr = PetscFree(rowlengths);CHKERRQ(ierr);
1155aabbc4fbSShri Abhyankar   }
1156aabbc4fbSShri Abhyankar   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1157aabbc4fbSShri Abhyankar   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1158aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1159aabbc4fbSShri Abhyankar }
1160aabbc4fbSShri Abhyankar 
1161eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1162eb91f321SVaclav Hapla {
1163eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1164eb91f321SVaclav Hapla   PetscErrorCode ierr;
1165eb91f321SVaclav Hapla 
1166eb91f321SVaclav Hapla   PetscFunctionBegin;
1167eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1168eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1169eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
1170eb91f321SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1171eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1172eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1173eb91f321SVaclav Hapla   if (isbinary) {
1174eb91f321SVaclav Hapla     ierr = MatLoad_SeqDense_Binary(newMat,viewer);CHKERRQ(ierr);
1175eb91f321SVaclav Hapla   } else if (ishdf5) {
1176eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
1177eb91f321SVaclav Hapla     ierr = MatLoad_Dense_HDF5(newMat,viewer);CHKERRQ(ierr);
1178eb91f321SVaclav Hapla #else
1179eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1180eb91f321SVaclav Hapla #endif
1181eb91f321SVaclav Hapla   } else {
1182eb91f321SVaclav 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);
1183eb91f321SVaclav Hapla   }
1184eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1185eb91f321SVaclav Hapla }
1186eb91f321SVaclav Hapla 
11876849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1188289bc588SBarry Smith {
1189932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1190dfbe8321SBarry Smith   PetscErrorCode    ierr;
119113f74950SBarry Smith   PetscInt          i,j;
11922dcb1b2aSMatthew Knepley   const char        *name;
119387828ca2SBarry Smith   PetscScalar       *v;
1194f3ef73ceSBarry Smith   PetscViewerFormat format;
11955f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1196ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
11975f481a85SSatish Balay #endif
1198932b0c3eSLois Curfman McInnes 
11993a40ed3dSBarry Smith   PetscFunctionBegin;
1200b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1201456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
12023a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1203fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1204d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1205d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
120644cd7ae7SLois Curfman McInnes       v    = a->v + i;
120777431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1208d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1209aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1210329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
121157622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1212329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
121357622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
12146831982aSBarry Smith         }
121580cd9d93SLois Curfman McInnes #else
12166831982aSBarry Smith         if (*v) {
121757622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
12186831982aSBarry Smith         }
121980cd9d93SLois Curfman McInnes #endif
12201b807ce4Svictorle         v += a->lda;
122180cd9d93SLois Curfman McInnes       }
1222b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
122380cd9d93SLois Curfman McInnes     }
1224d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
12253a40ed3dSBarry Smith   } else {
1226d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1227aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
122847989497SBarry Smith     /* determine if matrix has all real values */
122947989497SBarry Smith     v = a->v;
1230d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1231ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
123247989497SBarry Smith     }
123347989497SBarry Smith #endif
1234fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
12353a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1236d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1237d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1238fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1239ffac6cdbSBarry Smith     }
1240ffac6cdbSBarry Smith 
1241d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1242932b0c3eSLois Curfman McInnes       v = a->v + i;
1243d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1244aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
124547989497SBarry Smith         if (allreal) {
1246c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
124747989497SBarry Smith         } else {
1248c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
124947989497SBarry Smith         }
1250289bc588SBarry Smith #else
1251c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1252289bc588SBarry Smith #endif
12531b807ce4Svictorle         v += a->lda;
1254289bc588SBarry Smith       }
1255b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1256289bc588SBarry Smith     }
1257fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1258b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1259ffac6cdbSBarry Smith     }
1260d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1261da3a660dSBarry Smith   }
1262b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
12633a40ed3dSBarry Smith   PetscFunctionReturn(0);
1264289bc588SBarry Smith }
1265289bc588SBarry Smith 
12666849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_Binary(Mat A,PetscViewer viewer)
1267932b0c3eSLois Curfman McInnes {
1268932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
12696849ba73SBarry Smith   PetscErrorCode    ierr;
127013f74950SBarry Smith   int               fd;
1271d0f46423SBarry Smith   PetscInt          ict,j,n = A->cmap->n,m = A->rmap->n,i,*col_lens,nz = m*n;
1272f4403165SShri Abhyankar   PetscScalar       *v,*anonz,*vals;
1273f4403165SShri Abhyankar   PetscViewerFormat format;
1274932b0c3eSLois Curfman McInnes 
12753a40ed3dSBarry Smith   PetscFunctionBegin;
1276b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
127790ace30eSBarry Smith 
1278f4403165SShri Abhyankar   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1279f4403165SShri Abhyankar   if (format == PETSC_VIEWER_NATIVE) {
1280f4403165SShri Abhyankar     /* store the matrix as a dense matrix */
1281785e854fSJed Brown     ierr = PetscMalloc1(4,&col_lens);CHKERRQ(ierr);
12822205254eSKarl Rupp 
1283f4403165SShri Abhyankar     col_lens[0] = MAT_FILE_CLASSID;
1284f4403165SShri Abhyankar     col_lens[1] = m;
1285f4403165SShri Abhyankar     col_lens[2] = n;
1286f4403165SShri Abhyankar     col_lens[3] = MATRIX_BINARY_FORMAT_DENSE;
12872205254eSKarl Rupp 
1288f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,col_lens,4,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1289f4403165SShri Abhyankar     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1290f4403165SShri Abhyankar 
1291f4403165SShri Abhyankar     /* write out matrix, by rows */
1292854ce69bSBarry Smith     ierr = PetscMalloc1(m*n+1,&vals);CHKERRQ(ierr);
1293f4403165SShri Abhyankar     v    = a->v;
1294f4403165SShri Abhyankar     for (j=0; j<n; j++) {
1295f4403165SShri Abhyankar       for (i=0; i<m; i++) {
1296f4403165SShri Abhyankar         vals[j + i*n] = *v++;
1297f4403165SShri Abhyankar       }
1298f4403165SShri Abhyankar     }
1299f4403165SShri Abhyankar     ierr = PetscBinaryWrite(fd,vals,n*m,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1300f4403165SShri Abhyankar     ierr = PetscFree(vals);CHKERRQ(ierr);
1301f4403165SShri Abhyankar   } else {
1302854ce69bSBarry Smith     ierr = PetscMalloc1(4+nz,&col_lens);CHKERRQ(ierr);
13032205254eSKarl Rupp 
13040700a824SBarry Smith     col_lens[0] = MAT_FILE_CLASSID;
1305932b0c3eSLois Curfman McInnes     col_lens[1] = m;
1306932b0c3eSLois Curfman McInnes     col_lens[2] = n;
1307932b0c3eSLois Curfman McInnes     col_lens[3] = nz;
1308932b0c3eSLois Curfman McInnes 
1309932b0c3eSLois Curfman McInnes     /* store lengths of each row and write (including header) to file */
1310932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) col_lens[4+i] = n;
13116f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,4+m,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
1312932b0c3eSLois Curfman McInnes 
1313932b0c3eSLois Curfman McInnes     /* Possibly should write in smaller increments, not whole matrix at once? */
1314932b0c3eSLois Curfman McInnes     /* store column indices (zero start index) */
1315932b0c3eSLois Curfman McInnes     ict = 0;
1316932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1317932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) col_lens[ict++] = j;
1318932b0c3eSLois Curfman McInnes     }
13196f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
1320606d414cSSatish Balay     ierr = PetscFree(col_lens);CHKERRQ(ierr);
1321932b0c3eSLois Curfman McInnes 
1322932b0c3eSLois Curfman McInnes     /* store nonzero values */
1323854ce69bSBarry Smith     ierr = PetscMalloc1(nz+1,&anonz);CHKERRQ(ierr);
1324932b0c3eSLois Curfman McInnes     ict  = 0;
1325932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
1326932b0c3eSLois Curfman McInnes       v = a->v + i;
1327932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) {
13281b807ce4Svictorle         anonz[ict++] = *v; v += a->lda;
1329932b0c3eSLois Curfman McInnes       }
1330932b0c3eSLois Curfman McInnes     }
13316f69ff64SBarry Smith     ierr = PetscBinaryWrite(fd,anonz,nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr);
1332606d414cSSatish Balay     ierr = PetscFree(anonz);CHKERRQ(ierr);
1333f4403165SShri Abhyankar   }
13343a40ed3dSBarry Smith   PetscFunctionReturn(0);
1335932b0c3eSLois Curfman McInnes }
1336932b0c3eSLois Curfman McInnes 
13379804daf3SBarry Smith #include <petscdraw.h>
1338e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1339f1af5d2fSBarry Smith {
1340f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
1341f1af5d2fSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
13426849ba73SBarry Smith   PetscErrorCode    ierr;
1343383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1344383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
134587828ca2SBarry Smith   PetscScalar       *v = a->v;
1346b0a32e0cSBarry Smith   PetscViewer       viewer;
1347b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1348f3ef73ceSBarry Smith   PetscViewerFormat format;
1349f1af5d2fSBarry Smith 
1350f1af5d2fSBarry Smith   PetscFunctionBegin;
1351f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1352b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1353b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1354f1af5d2fSBarry Smith 
1355f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1356383922c3SLisandro Dalcin 
1357fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1358383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1359f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1360f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1361383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1362f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1363f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1364f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1365329f5518SBarry Smith         if (PetscRealPart(v[j*m+i]) >  0.) {
1366b0a32e0cSBarry Smith           color = PETSC_DRAW_RED;
1367329f5518SBarry Smith         } else if (PetscRealPart(v[j*m+i]) <  0.) {
1368b0a32e0cSBarry Smith           color = PETSC_DRAW_BLUE;
1369f1af5d2fSBarry Smith         } else {
1370f1af5d2fSBarry Smith           continue;
1371f1af5d2fSBarry Smith         }
1372b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1373f1af5d2fSBarry Smith       }
1374f1af5d2fSBarry Smith     }
1375383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1376f1af5d2fSBarry Smith   } else {
1377f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1378f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1379b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1380b05fc000SLisandro Dalcin     PetscDraw popup;
1381b05fc000SLisandro Dalcin 
1382f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1383f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1384f1af5d2fSBarry Smith     }
1385383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1386b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
138745f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1388383922c3SLisandro Dalcin 
1389383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1390f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1391f1af5d2fSBarry Smith       x_l = j;
1392f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1393f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1394f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1395f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1396b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1397b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1398f1af5d2fSBarry Smith       }
1399f1af5d2fSBarry Smith     }
1400383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1401f1af5d2fSBarry Smith   }
1402f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1403f1af5d2fSBarry Smith }
1404f1af5d2fSBarry Smith 
1405e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1406f1af5d2fSBarry Smith {
1407b0a32e0cSBarry Smith   PetscDraw      draw;
1408ace3abfcSBarry Smith   PetscBool      isnull;
1409329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1410dfbe8321SBarry Smith   PetscErrorCode ierr;
1411f1af5d2fSBarry Smith 
1412f1af5d2fSBarry Smith   PetscFunctionBegin;
1413b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1414b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1415abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1416f1af5d2fSBarry Smith 
1417d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1418f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1419b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1420832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1421b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
14220298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1423832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1424f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1425f1af5d2fSBarry Smith }
1426f1af5d2fSBarry Smith 
1427dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1428932b0c3eSLois Curfman McInnes {
1429dfbe8321SBarry Smith   PetscErrorCode ierr;
1430ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1431932b0c3eSLois Curfman McInnes 
14323a40ed3dSBarry Smith   PetscFunctionBegin;
1433251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1434251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1435251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
14360f5bd95cSBarry Smith 
1437c45a1595SBarry Smith   if (iascii) {
1438c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
14390f5bd95cSBarry Smith   } else if (isbinary) {
14403a40ed3dSBarry Smith     ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr);
1441f1af5d2fSBarry Smith   } else if (isdraw) {
1442f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1443932b0c3eSLois Curfman McInnes   }
14443a40ed3dSBarry Smith   PetscFunctionReturn(0);
1445932b0c3eSLois Curfman McInnes }
1446289bc588SBarry Smith 
1447d3042a70SBarry Smith static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar array[])
1448d3042a70SBarry Smith {
1449d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1450d3042a70SBarry Smith 
1451d3042a70SBarry Smith   PetscFunctionBegin;
1452d3042a70SBarry Smith   a->unplacedarray       = a->v;
1453d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1454d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1455d3042a70SBarry Smith   PetscFunctionReturn(0);
1456d3042a70SBarry Smith }
1457d3042a70SBarry Smith 
1458d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1459d3042a70SBarry Smith {
1460d3042a70SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1461d3042a70SBarry Smith 
1462d3042a70SBarry Smith   PetscFunctionBegin;
1463d3042a70SBarry Smith   a->v             = a->unplacedarray;
1464d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1465d3042a70SBarry Smith   a->unplacedarray = NULL;
1466d3042a70SBarry Smith   PetscFunctionReturn(0);
1467d3042a70SBarry Smith }
1468d3042a70SBarry Smith 
1469e0877f53SBarry Smith static PetscErrorCode MatDestroy_SeqDense(Mat mat)
1470289bc588SBarry Smith {
1471ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1472dfbe8321SBarry Smith   PetscErrorCode ierr;
147390f02eecSBarry Smith 
14743a40ed3dSBarry Smith   PetscFunctionBegin;
1475aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1476d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1477a5a9c739SBarry Smith #endif
147805b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1479a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1480abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
14816857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1482bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1483dbd8c25aSHong Zhang 
1484dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
148549a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1486bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
1487d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1488d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
1489bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
14908baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
14918baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
14928baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
14938baccfbdSHong Zhang #endif
1494bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
1495bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1496bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1497bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
1498*a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1499*a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1500*a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
1501abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatPtAP_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
15023bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
15033bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
15043bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
150586aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
150686aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
15073a40ed3dSBarry Smith   PetscFunctionReturn(0);
1508289bc588SBarry Smith }
1509289bc588SBarry Smith 
1510e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1511289bc588SBarry Smith {
1512c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
15136849ba73SBarry Smith   PetscErrorCode ierr;
151413f74950SBarry Smith   PetscInt       k,j,m,n,M;
151587828ca2SBarry Smith   PetscScalar    *v,tmp;
151648b35521SBarry Smith 
15173a40ed3dSBarry Smith   PetscFunctionBegin;
1518d0f46423SBarry Smith   v = mat->v; m = A->rmap->n; M = mat->lda; n = A->cmap->n;
15192847e3fdSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX && m == n) { /* in place transpose */
1520d3e5ee88SLois Curfman McInnes     for (j=0; j<m; j++) {
1521289bc588SBarry Smith       for (k=0; k<j; k++) {
15221b807ce4Svictorle         tmp        = v[j + k*M];
15231b807ce4Svictorle         v[j + k*M] = v[k + j*M];
15241b807ce4Svictorle         v[k + j*M] = tmp;
1525289bc588SBarry Smith       }
1526289bc588SBarry Smith     }
15273a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1528d3e5ee88SLois Curfman McInnes     Mat          tmat;
1529ec8511deSBarry Smith     Mat_SeqDense *tmatd;
153087828ca2SBarry Smith     PetscScalar  *v2;
1531af36a384SStefano Zampini     PetscInt     M2;
1532ea709b57SSatish Balay 
15332847e3fdSStefano Zampini     if (reuse != MAT_REUSE_MATRIX) {
1534ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1535d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
15367adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
15370298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1538fc4dec0aSBarry Smith     } else {
1539fc4dec0aSBarry Smith       tmat = *matout;
1540fc4dec0aSBarry Smith     }
1541ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1542af36a384SStefano Zampini     v = mat->v; v2 = tmatd->v; M2 = tmatd->lda;
1543d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1544af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1545d3e5ee88SLois Curfman McInnes     }
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;
156013f74950SBarry Smith   PetscInt     i,j;
1561a2ea699eSBarry Smith   PetscScalar  *v1,*v2;
15629ea5d5aeSSatish Balay 
15633a40ed3dSBarry Smith   PetscFunctionBegin;
1564d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1565d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1566d0f46423SBarry Smith   for (i=0; i<A1->rmap->n; i++) {
15671b807ce4Svictorle     v1 = mat1->v+i; v2 = mat2->v+i;
1568d0f46423SBarry Smith     for (j=0; j<A1->cmap->n; j++) {
15693a40ed3dSBarry Smith       if (*v1 != *v2) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
15701b807ce4Svictorle       v1 += mat1->lda; v2 += mat2->lda;
15711b807ce4Svictorle     }
1572289bc588SBarry Smith   }
157377c4ece6SBarry Smith   *flg = PETSC_TRUE;
15743a40ed3dSBarry Smith   PetscFunctionReturn(0);
1575289bc588SBarry Smith }
1576289bc588SBarry Smith 
1577e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1578289bc588SBarry Smith {
1579c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
1580dfbe8321SBarry Smith   PetscErrorCode ierr;
158113f74950SBarry Smith   PetscInt       i,n,len;
158287828ca2SBarry Smith   PetscScalar    *x,zero = 0.0;
158344cd7ae7SLois Curfman McInnes 
15843a40ed3dSBarry Smith   PetscFunctionBegin;
15852dcb1b2aSMatthew Knepley   ierr = VecSet(v,zero);CHKERRQ(ierr);
15867a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
15871ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1588d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1589e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
159044cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
15911b807ce4Svictorle     x[i] = mat->v[i*mat->lda + i];
1592289bc588SBarry Smith   }
15931ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
15943a40ed3dSBarry Smith   PetscFunctionReturn(0);
1595289bc588SBarry Smith }
1596289bc588SBarry Smith 
1597e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1598289bc588SBarry Smith {
1599c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1600f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1601f1ceaac6SMatthew G. Knepley   PetscScalar       x,*v;
1602dfbe8321SBarry Smith   PetscErrorCode    ierr;
1603d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
160455659b69SBarry Smith 
16053a40ed3dSBarry Smith   PetscFunctionBegin;
160628988994SBarry Smith   if (ll) {
16077a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1608f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1609e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1610da3a660dSBarry Smith     for (i=0; i<m; i++) {
1611da3a660dSBarry Smith       x = l[i];
1612da3a660dSBarry Smith       v = mat->v + i;
1613b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1614da3a660dSBarry Smith     }
1615f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1616eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1617da3a660dSBarry Smith   }
161828988994SBarry Smith   if (rr) {
16197a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1620f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1621e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1622da3a660dSBarry Smith     for (i=0; i<n; i++) {
1623da3a660dSBarry Smith       x = r[i];
1624b43bac26SStefano Zampini       v = mat->v + i*mat->lda;
16252205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1626da3a660dSBarry Smith     }
1627f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1628eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1629da3a660dSBarry Smith   }
16303a40ed3dSBarry Smith   PetscFunctionReturn(0);
1631289bc588SBarry Smith }
1632289bc588SBarry Smith 
1633e0877f53SBarry Smith static PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1634289bc588SBarry Smith {
1635c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
163687828ca2SBarry Smith   PetscScalar    *v   = mat->v;
1637329f5518SBarry Smith   PetscReal      sum  = 0.0;
1638d0f46423SBarry Smith   PetscInt       lda  =mat->lda,m=A->rmap->n,i,j;
1639efee365bSSatish Balay   PetscErrorCode ierr;
164055659b69SBarry Smith 
16413a40ed3dSBarry Smith   PetscFunctionBegin;
1642289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1643a5ce6ee0Svictorle     if (lda>m) {
1644d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1645a5ce6ee0Svictorle         v = mat->v+j*lda;
1646a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1647a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1648a5ce6ee0Svictorle         }
1649a5ce6ee0Svictorle       }
1650a5ce6ee0Svictorle     } else {
1651570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1652570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1653570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1654570b7f6dSBarry Smith     }
1655570b7f6dSBarry Smith #else
1656d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1657329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1658289bc588SBarry Smith       }
1659a5ce6ee0Svictorle     }
16608f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1661570b7f6dSBarry Smith #endif
1662dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16633a40ed3dSBarry Smith   } else if (type == NORM_1) {
1664064f8208SBarry Smith     *nrm = 0.0;
1665d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
16661b807ce4Svictorle       v   = mat->v + j*mat->lda;
1667289bc588SBarry Smith       sum = 0.0;
1668d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
166933a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1670289bc588SBarry Smith       }
1671064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1672289bc588SBarry Smith     }
1673eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16743a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1675064f8208SBarry Smith     *nrm = 0.0;
1676d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1677289bc588SBarry Smith       v   = mat->v + j;
1678289bc588SBarry Smith       sum = 0.0;
1679d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
16801b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1681289bc588SBarry Smith       }
1682064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1683289bc588SBarry Smith     }
1684eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1685e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
16863a40ed3dSBarry Smith   PetscFunctionReturn(0);
1687289bc588SBarry Smith }
1688289bc588SBarry Smith 
1689e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1690289bc588SBarry Smith {
1691c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
169263ba0a88SBarry Smith   PetscErrorCode ierr;
169367e560aaSBarry Smith 
16943a40ed3dSBarry Smith   PetscFunctionBegin;
1695b5a2b587SKris Buschelman   switch (op) {
1696b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
16974e0d8c25SBarry Smith     aij->roworiented = flg;
1698b5a2b587SKris Buschelman     break;
1699512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1700b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
17013971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
17024e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
170313fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1704b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1705b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
17060f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
17075021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
1708071fcb05SBarry Smith   case MAT_SORTED_FULL:
17095021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
17105021d80fSJed Brown     break;
17115021d80fSJed Brown   case MAT_SPD:
171277e54ba9SKris Buschelman   case MAT_SYMMETRIC:
171377e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
17149a4540c5SBarry Smith   case MAT_HERMITIAN:
17159a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
17165021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
171777e54ba9SKris Buschelman     break;
1718b5a2b587SKris Buschelman   default:
1719e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
17203a40ed3dSBarry Smith   }
17213a40ed3dSBarry Smith   PetscFunctionReturn(0);
1722289bc588SBarry Smith }
1723289bc588SBarry Smith 
1724e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
17256f0a148fSBarry Smith {
1726ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
17276849ba73SBarry Smith   PetscErrorCode ierr;
1728d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
17293a40ed3dSBarry Smith 
17303a40ed3dSBarry Smith   PetscFunctionBegin;
1731a5ce6ee0Svictorle   if (lda>m) {
1732d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1733580bdb30SBarry Smith       ierr = PetscArrayzero(l->v+j*lda,m);CHKERRQ(ierr);
1734a5ce6ee0Svictorle     }
1735a5ce6ee0Svictorle   } else {
1736580bdb30SBarry Smith     ierr = PetscArrayzero(l->v,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
1737a5ce6ee0Svictorle   }
17383a40ed3dSBarry Smith   PetscFunctionReturn(0);
17396f0a148fSBarry Smith }
17406f0a148fSBarry Smith 
1741e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
17426f0a148fSBarry Smith {
174397b48c8fSBarry Smith   PetscErrorCode    ierr;
1744ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1745b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
174697b48c8fSBarry Smith   PetscScalar       *slot,*bb;
174797b48c8fSBarry Smith   const PetscScalar *xx;
174855659b69SBarry Smith 
17493a40ed3dSBarry Smith   PetscFunctionBegin;
1750b9679d65SBarry Smith #if defined(PETSC_USE_DEBUG)
1751b9679d65SBarry Smith   for (i=0; i<N; i++) {
1752b9679d65SBarry Smith     if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1753b9679d65SBarry 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);
1754b9679d65SBarry Smith   }
1755b9679d65SBarry Smith #endif
1756b9679d65SBarry Smith 
175797b48c8fSBarry Smith   /* fix right hand side if needed */
175897b48c8fSBarry Smith   if (x && b) {
175997b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
176097b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
17612205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
176297b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
176397b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
176497b48c8fSBarry Smith   }
176597b48c8fSBarry Smith 
17666f0a148fSBarry Smith   for (i=0; i<N; i++) {
17676f0a148fSBarry Smith     slot = l->v + rows[i];
1768b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
17696f0a148fSBarry Smith   }
1770f4df32b1SMatthew Knepley   if (diag != 0.0) {
1771b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
17726f0a148fSBarry Smith     for (i=0; i<N; i++) {
1773b9679d65SBarry Smith       slot  = l->v + (m+1)*rows[i];
1774f4df32b1SMatthew Knepley       *slot = diag;
17756f0a148fSBarry Smith     }
17766f0a148fSBarry Smith   }
17773a40ed3dSBarry Smith   PetscFunctionReturn(0);
17786f0a148fSBarry Smith }
1779557bce09SLois Curfman McInnes 
178049a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
178149a6ff4bSBarry Smith {
178249a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
178349a6ff4bSBarry Smith 
178449a6ff4bSBarry Smith   PetscFunctionBegin;
178549a6ff4bSBarry Smith   *lda = mat->lda;
178649a6ff4bSBarry Smith   PetscFunctionReturn(0);
178749a6ff4bSBarry Smith }
178849a6ff4bSBarry Smith 
1789e0877f53SBarry Smith static PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar *array[])
179064e87e97SBarry Smith {
1791c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
17923a40ed3dSBarry Smith 
17933a40ed3dSBarry Smith   PetscFunctionBegin;
1794e32f2f54SBarry Smith   if (mat->lda != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get array for Dense matrices with LDA different from number of rows");
179564e87e97SBarry Smith   *array = mat->v;
17963a40ed3dSBarry Smith   PetscFunctionReturn(0);
179764e87e97SBarry Smith }
17980754003eSLois Curfman McInnes 
1799e0877f53SBarry Smith static PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar *array[])
1800ff14e315SSatish Balay {
18013a40ed3dSBarry Smith   PetscFunctionBegin;
18023a40ed3dSBarry Smith   PetscFunctionReturn(0);
1803ff14e315SSatish Balay }
18040754003eSLois Curfman McInnes 
1805dec5eb66SMatthew G Knepley /*@C
180649a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
180749a6ff4bSBarry Smith 
180849a6ff4bSBarry Smith    Logically Collective on Mat
180949a6ff4bSBarry Smith 
181049a6ff4bSBarry Smith    Input Parameter:
181149a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
181249a6ff4bSBarry Smith 
181349a6ff4bSBarry Smith    Output Parameter:
181449a6ff4bSBarry Smith .   lda - the leading dimension
181549a6ff4bSBarry Smith 
181649a6ff4bSBarry Smith    Level: intermediate
181749a6ff4bSBarry Smith 
181849a6ff4bSBarry Smith .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatSeqDenseSetLDA()
181949a6ff4bSBarry Smith @*/
182049a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
182149a6ff4bSBarry Smith {
182249a6ff4bSBarry Smith   PetscErrorCode ierr;
182349a6ff4bSBarry Smith 
182449a6ff4bSBarry Smith   PetscFunctionBegin;
182549a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
182649a6ff4bSBarry Smith   PetscFunctionReturn(0);
182749a6ff4bSBarry Smith }
182849a6ff4bSBarry Smith 
182949a6ff4bSBarry Smith /*@C
18308c778c55SBarry Smith    MatDenseGetArray - gives access to the array where the data for a SeqDense matrix is stored
183173a71a0fSBarry Smith 
18328572280aSBarry Smith    Logically Collective on Mat
183373a71a0fSBarry Smith 
183473a71a0fSBarry Smith    Input Parameter:
1835579dbff0SBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
183673a71a0fSBarry Smith 
183773a71a0fSBarry Smith    Output Parameter:
183873a71a0fSBarry Smith .   array - pointer to the data
183973a71a0fSBarry Smith 
184073a71a0fSBarry Smith    Level: intermediate
184173a71a0fSBarry Smith 
18428572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
184373a71a0fSBarry Smith @*/
18448c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
184573a71a0fSBarry Smith {
184673a71a0fSBarry Smith   PetscErrorCode ierr;
184773a71a0fSBarry Smith 
184873a71a0fSBarry Smith   PetscFunctionBegin;
18498c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
185073a71a0fSBarry Smith   PetscFunctionReturn(0);
185173a71a0fSBarry Smith }
185273a71a0fSBarry Smith 
1853dec5eb66SMatthew G Knepley /*@C
1854579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
185573a71a0fSBarry Smith 
18568572280aSBarry Smith    Logically Collective on Mat
18578572280aSBarry Smith 
18588572280aSBarry Smith    Input Parameters:
1859a2b725a8SWilliam Gropp +  mat - a MATSEQDENSE or MATMPIDENSE matrix
1860a2b725a8SWilliam Gropp -  array - pointer to the data
18618572280aSBarry Smith 
18628572280aSBarry Smith    Level: intermediate
18638572280aSBarry Smith 
18648572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
18658572280aSBarry Smith @*/
18668572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
18678572280aSBarry Smith {
18688572280aSBarry Smith   PetscErrorCode ierr;
18698572280aSBarry Smith 
18708572280aSBarry Smith   PetscFunctionBegin;
18718572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
18728572280aSBarry Smith   if (array) *array = NULL;
18738572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
18748572280aSBarry Smith   PetscFunctionReturn(0);
18758572280aSBarry Smith }
18768572280aSBarry Smith 
18778572280aSBarry Smith /*@C
18788572280aSBarry Smith    MatDenseGetArrayRead - gives access to the array where the data for a SeqDense matrix is stored
18798572280aSBarry Smith 
18808572280aSBarry Smith    Not Collective
18818572280aSBarry Smith 
18828572280aSBarry Smith    Input Parameter:
18838572280aSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
18848572280aSBarry Smith 
18858572280aSBarry Smith    Output Parameter:
18868572280aSBarry Smith .   array - pointer to the data
18878572280aSBarry Smith 
18888572280aSBarry Smith    Level: intermediate
18898572280aSBarry Smith 
18908572280aSBarry Smith .seealso: MatDenseRestoreArray(), MatDenseGetArray(), MatDenseRestoreArrayRead()
18918572280aSBarry Smith @*/
18928572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
18938572280aSBarry Smith {
18948572280aSBarry Smith   PetscErrorCode ierr;
18958572280aSBarry Smith 
18968572280aSBarry Smith   PetscFunctionBegin;
18978572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
18988572280aSBarry Smith   PetscFunctionReturn(0);
18998572280aSBarry Smith }
19008572280aSBarry Smith 
19018572280aSBarry Smith /*@C
19028572280aSBarry Smith    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
19038572280aSBarry Smith 
190473a71a0fSBarry Smith    Not Collective
190573a71a0fSBarry Smith 
190673a71a0fSBarry Smith    Input Parameters:
1907a2b725a8SWilliam Gropp +  mat - a MATSEQDENSE or MATMPIDENSE matrix
1908a2b725a8SWilliam Gropp -  array - pointer to the data
190973a71a0fSBarry Smith 
191073a71a0fSBarry Smith    Level: intermediate
191173a71a0fSBarry Smith 
19128572280aSBarry Smith .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArray()
191373a71a0fSBarry Smith @*/
19148572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
191573a71a0fSBarry Smith {
191673a71a0fSBarry Smith   PetscErrorCode ierr;
191773a71a0fSBarry Smith 
191873a71a0fSBarry Smith   PetscFunctionBegin;
19198572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
19208572280aSBarry Smith   if (array) *array = NULL;
192173a71a0fSBarry Smith   PetscFunctionReturn(0);
192273a71a0fSBarry Smith }
192373a71a0fSBarry Smith 
19247dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
19250754003eSLois Curfman McInnes {
1926c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
19276849ba73SBarry Smith   PetscErrorCode ierr;
19285d0c19d7SBarry Smith   PetscInt       i,j,nrows,ncols;
19295d0c19d7SBarry Smith   const PetscInt *irow,*icol;
193087828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
19310754003eSLois Curfman McInnes   Mat            newmat;
19320754003eSLois Curfman McInnes 
19333a40ed3dSBarry Smith   PetscFunctionBegin;
193478b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
193578b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1936e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1937e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
19380754003eSLois Curfman McInnes 
1939182d2002SSatish Balay   /* Check submatrixcall */
1940182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
194113f74950SBarry Smith     PetscInt n_cols,n_rows;
1942182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
194321a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
1944f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
1945c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
194621a2c019SBarry Smith     }
1947182d2002SSatish Balay     newmat = *B;
1948182d2002SSatish Balay   } else {
19490754003eSLois Curfman McInnes     /* Create and fill new matrix */
1950ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
1951f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
19527adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
19530298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
1954182d2002SSatish Balay   }
1955182d2002SSatish Balay 
1956182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1957182d2002SSatish Balay   bv = ((Mat_SeqDense*)newmat->data)->v;
1958182d2002SSatish Balay 
1959182d2002SSatish Balay   for (i=0; i<ncols; i++) {
19606de62eeeSBarry Smith     av = v + mat->lda*icol[i];
19612205254eSKarl Rupp     for (j=0; j<nrows; j++) *bv++ = av[irow[j]];
19620754003eSLois Curfman McInnes   }
1963182d2002SSatish Balay 
1964182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
19656d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19666d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
19670754003eSLois Curfman McInnes 
19680754003eSLois Curfman McInnes   /* Free work space */
196978b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
197078b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1971182d2002SSatish Balay   *B   = newmat;
19723a40ed3dSBarry Smith   PetscFunctionReturn(0);
19730754003eSLois Curfman McInnes }
19740754003eSLois Curfman McInnes 
19757dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
1976905e6a2fSBarry Smith {
19776849ba73SBarry Smith   PetscErrorCode ierr;
197813f74950SBarry Smith   PetscInt       i;
1979905e6a2fSBarry Smith 
19803a40ed3dSBarry Smith   PetscFunctionBegin;
1981905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1982df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
1983905e6a2fSBarry Smith   }
1984905e6a2fSBarry Smith 
1985905e6a2fSBarry Smith   for (i=0; i<n; i++) {
19867dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1987905e6a2fSBarry Smith   }
19883a40ed3dSBarry Smith   PetscFunctionReturn(0);
1989905e6a2fSBarry Smith }
1990905e6a2fSBarry Smith 
1991e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
1992c0aa2d19SHong Zhang {
1993c0aa2d19SHong Zhang   PetscFunctionBegin;
1994c0aa2d19SHong Zhang   PetscFunctionReturn(0);
1995c0aa2d19SHong Zhang }
1996c0aa2d19SHong Zhang 
1997e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
1998c0aa2d19SHong Zhang {
1999c0aa2d19SHong Zhang   PetscFunctionBegin;
2000c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2001c0aa2d19SHong Zhang }
2002c0aa2d19SHong Zhang 
2003e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
20044b0e389bSBarry Smith {
20054b0e389bSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
20066849ba73SBarry Smith   PetscErrorCode ierr;
2007d0f46423SBarry Smith   PetscInt       lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
20083a40ed3dSBarry Smith 
20093a40ed3dSBarry Smith   PetscFunctionBegin;
201033f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
201133f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
2012cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
20133a40ed3dSBarry Smith     PetscFunctionReturn(0);
20143a40ed3dSBarry Smith   }
2015e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
2016a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
20170dbb7854Svictorle     for (j=0; j<n; j++) {
2018580bdb30SBarry Smith       ierr = PetscArraycpy(b->v+j*lda2,a->v+j*lda1,m);CHKERRQ(ierr);
2019a5ce6ee0Svictorle     }
2020a5ce6ee0Svictorle   } else {
2021580bdb30SBarry Smith     ierr = PetscArraycpy(b->v,a->v,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2022a5ce6ee0Svictorle   }
2023cdc753b6SBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr);
2024273d9f13SBarry Smith   PetscFunctionReturn(0);
2025273d9f13SBarry Smith }
2026273d9f13SBarry Smith 
2027e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
2028273d9f13SBarry Smith {
2029dfbe8321SBarry Smith   PetscErrorCode ierr;
2030273d9f13SBarry Smith 
2031273d9f13SBarry Smith   PetscFunctionBegin;
2032273d9f13SBarry Smith   ierr =  MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
20333a40ed3dSBarry Smith   PetscFunctionReturn(0);
20344b0e389bSBarry Smith }
20354b0e389bSBarry Smith 
2036ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2037ba337c44SJed Brown {
2038ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
2039ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
2040ba337c44SJed Brown   PetscScalar  *aa = a->v;
2041ba337c44SJed Brown 
2042ba337c44SJed Brown   PetscFunctionBegin;
2043ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2044ba337c44SJed Brown   PetscFunctionReturn(0);
2045ba337c44SJed Brown }
2046ba337c44SJed Brown 
2047ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2048ba337c44SJed Brown {
2049ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
2050ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
2051ba337c44SJed Brown   PetscScalar  *aa = a->v;
2052ba337c44SJed Brown 
2053ba337c44SJed Brown   PetscFunctionBegin;
2054ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2055ba337c44SJed Brown   PetscFunctionReturn(0);
2056ba337c44SJed Brown }
2057ba337c44SJed Brown 
2058ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2059ba337c44SJed Brown {
2060ba337c44SJed Brown   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
2061ba337c44SJed Brown   PetscInt     i,nz = A->rmap->n*A->cmap->n;
2062ba337c44SJed Brown   PetscScalar  *aa = a->v;
2063ba337c44SJed Brown 
2064ba337c44SJed Brown   PetscFunctionBegin;
2065ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
2066ba337c44SJed Brown   PetscFunctionReturn(0);
2067ba337c44SJed Brown }
2068284134d9SBarry Smith 
2069a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
2070150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
2071a9fe9ddaSSatish Balay {
2072a9fe9ddaSSatish Balay   PetscErrorCode ierr;
2073a9fe9ddaSSatish Balay 
2074a9fe9ddaSSatish Balay   PetscFunctionBegin;
2075a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
20763ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2077a9fe9ddaSSatish Balay     ierr = MatMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
20783ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2079a9fe9ddaSSatish Balay   }
20803ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2081a9fe9ddaSSatish Balay   ierr = MatMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
20823ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2083a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2084a9fe9ddaSSatish Balay }
2085a9fe9ddaSSatish Balay 
2086a9fe9ddaSSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
2087a9fe9ddaSSatish Balay {
2088ee16a9a1SHong Zhang   PetscErrorCode ierr;
2089d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
2090ee16a9a1SHong Zhang   Mat            Cmat;
2091a9fe9ddaSSatish Balay 
2092ee16a9a1SHong Zhang   PetscFunctionBegin;
2093e32f2f54SBarry Smith   if (A->cmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->cmap->n %d != B->rmap->n %d\n",A->cmap->n,B->rmap->n);
2094ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
2095ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
2096ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
20970298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
2098d73949e8SHong Zhang 
2099ee16a9a1SHong Zhang   *C = Cmat;
2100ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2101ee16a9a1SHong Zhang }
2102a9fe9ddaSSatish Balay 
2103a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2104a9fe9ddaSSatish Balay {
2105a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2106a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2107a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
21080805154bSBarry Smith   PetscBLASInt   m,n,k;
2109a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
2110c5df96a5SBarry Smith   PetscErrorCode ierr;
2111fd4e9aacSBarry Smith   PetscBool      flg;
2112a9fe9ddaSSatish Balay 
2113a9fe9ddaSSatish Balay   PetscFunctionBegin;
2114fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQDENSE,&flg);CHKERRQ(ierr);
2115fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Second matrix must be dense");
2116fd4e9aacSBarry Smith 
2117fd4e9aacSBarry Smith   /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/
2118fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr);
2119fd4e9aacSBarry Smith   if (flg) {
2120fd4e9aacSBarry Smith     C->ops->matmultnumeric = MatMatMultNumeric_SeqAIJ_SeqDense;
2121fd4e9aacSBarry Smith     ierr = (*C->ops->matmultnumeric)(A,B,C);CHKERRQ(ierr);
2122fd4e9aacSBarry Smith     PetscFunctionReturn(0);
2123fd4e9aacSBarry Smith   }
2124*a001520aSPierre Jolivet   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQBAIJ,&flg);CHKERRQ(ierr);
2125*a001520aSPierre Jolivet   if (flg) {
2126*a001520aSPierre Jolivet     C->ops->matmultnumeric = MatMatMultNumeric_SeqBAIJ_SeqDense;
2127*a001520aSPierre Jolivet     ierr = (*C->ops->matmultnumeric)(A,B,C);CHKERRQ(ierr);
2128*a001520aSPierre Jolivet     PetscFunctionReturn(0);
2129*a001520aSPierre Jolivet   }
2130fd4e9aacSBarry Smith 
2131fd4e9aacSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&flg);CHKERRQ(ierr);
2132fd4e9aacSBarry Smith   if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"First matrix must be dense");
21338208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
21348208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2135c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
213649d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
21375ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2138a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2139a9fe9ddaSSatish Balay }
2140a9fe9ddaSSatish Balay 
214169f65d41SStefano Zampini PetscErrorCode MatMatTransposeMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
214269f65d41SStefano Zampini {
214369f65d41SStefano Zampini   PetscErrorCode ierr;
214469f65d41SStefano Zampini 
214569f65d41SStefano Zampini   PetscFunctionBegin;
214669f65d41SStefano Zampini   if (scall == MAT_INITIAL_MATRIX) {
214769f65d41SStefano Zampini     ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
214869f65d41SStefano Zampini     ierr = MatMatTransposeMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
214969f65d41SStefano Zampini     ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);
215069f65d41SStefano Zampini   }
215169f65d41SStefano Zampini   ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
215269f65d41SStefano Zampini   ierr = MatMatTransposeMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
215369f65d41SStefano Zampini   ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);
215469f65d41SStefano Zampini   PetscFunctionReturn(0);
215569f65d41SStefano Zampini }
215669f65d41SStefano Zampini 
215769f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
215869f65d41SStefano Zampini {
215969f65d41SStefano Zampini   PetscErrorCode ierr;
216069f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
216169f65d41SStefano Zampini   Mat            Cmat;
216269f65d41SStefano Zampini 
216369f65d41SStefano Zampini   PetscFunctionBegin;
216469f65d41SStefano Zampini   if (A->cmap->n != B->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->cmap->n %d != B->cmap->n %d\n",A->cmap->n,B->cmap->n);
216569f65d41SStefano Zampini   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
216669f65d41SStefano Zampini   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
216769f65d41SStefano Zampini   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
216869f65d41SStefano Zampini   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
216969f65d41SStefano Zampini 
217069f65d41SStefano Zampini   Cmat->assembled = PETSC_TRUE;
217169f65d41SStefano Zampini 
217269f65d41SStefano Zampini   *C = Cmat;
217369f65d41SStefano Zampini   PetscFunctionReturn(0);
217469f65d41SStefano Zampini }
217569f65d41SStefano Zampini 
217669f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
217769f65d41SStefano Zampini {
217869f65d41SStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
217969f65d41SStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
218069f65d41SStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
218169f65d41SStefano Zampini   PetscBLASInt   m,n,k;
218269f65d41SStefano Zampini   PetscScalar    _DOne=1.0,_DZero=0.0;
218369f65d41SStefano Zampini   PetscErrorCode ierr;
218469f65d41SStefano Zampini 
218569f65d41SStefano Zampini   PetscFunctionBegin;
218649d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
218749d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
218869f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
218949d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
219069f65d41SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
219169f65d41SStefano Zampini   PetscFunctionReturn(0);
219269f65d41SStefano Zampini }
219369f65d41SStefano Zampini 
219475648e8dSHong Zhang PetscErrorCode MatTransposeMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
2195a9fe9ddaSSatish Balay {
2196a9fe9ddaSSatish Balay   PetscErrorCode ierr;
2197a9fe9ddaSSatish Balay 
2198a9fe9ddaSSatish Balay   PetscFunctionBegin;
2199a9fe9ddaSSatish Balay   if (scall == MAT_INITIAL_MATRIX) {
22003ff4c91cSHong Zhang     ierr = PetscLogEventBegin(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
220175648e8dSHong Zhang     ierr = MatTransposeMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr);
22023ff4c91cSHong Zhang     ierr = PetscLogEventEnd(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr);
2203a9fe9ddaSSatish Balay   }
22043ff4c91cSHong Zhang   ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
220575648e8dSHong Zhang   ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr);
22063ff4c91cSHong Zhang   ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr);
2207a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2208a9fe9ddaSSatish Balay }
2209a9fe9ddaSSatish Balay 
221075648e8dSHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
2211a9fe9ddaSSatish Balay {
2212ee16a9a1SHong Zhang   PetscErrorCode ierr;
2213d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
2214ee16a9a1SHong Zhang   Mat            Cmat;
2215a9fe9ddaSSatish Balay 
2216ee16a9a1SHong Zhang   PetscFunctionBegin;
2217e32f2f54SBarry Smith   if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->rmap->n %d != B->rmap->n %d\n",A->rmap->n,B->rmap->n);
2218ee16a9a1SHong Zhang   ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr);
2219ee16a9a1SHong Zhang   ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr);
2220ee16a9a1SHong Zhang   ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr);
22210298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr);
22222205254eSKarl Rupp 
2223ee16a9a1SHong Zhang   Cmat->assembled = PETSC_TRUE;
22242205254eSKarl Rupp 
2225ee16a9a1SHong Zhang   *C = Cmat;
2226ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2227ee16a9a1SHong Zhang }
2228a9fe9ddaSSatish Balay 
222975648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2230a9fe9ddaSSatish Balay {
2231a9fe9ddaSSatish Balay   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2232a9fe9ddaSSatish Balay   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2233a9fe9ddaSSatish Balay   Mat_SeqDense   *c = (Mat_SeqDense*)C->data;
22340805154bSBarry Smith   PetscBLASInt   m,n,k;
2235a9fe9ddaSSatish Balay   PetscScalar    _DOne=1.0,_DZero=0.0;
2236c5df96a5SBarry Smith   PetscErrorCode ierr;
2237a9fe9ddaSSatish Balay 
2238a9fe9ddaSSatish Balay   PetscFunctionBegin;
22398208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
22408208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2241c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
224249d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
22435ca1cc5dSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda));
2244a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2245a9fe9ddaSSatish Balay }
2246985db425SBarry Smith 
2247e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2248985db425SBarry Smith {
2249985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2250985db425SBarry Smith   PetscErrorCode ierr;
2251d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
2252985db425SBarry Smith   PetscScalar    *x;
2253985db425SBarry Smith   MatScalar      *aa = a->v;
2254985db425SBarry Smith 
2255985db425SBarry Smith   PetscFunctionBegin;
2256e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2257985db425SBarry Smith 
2258985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2259985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2260985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2261e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2262985db425SBarry Smith   for (i=0; i<m; i++) {
2263985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2264985db425SBarry Smith     for (j=1; j<n; j++) {
2265985db425SBarry Smith       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
2266985db425SBarry Smith     }
2267985db425SBarry Smith   }
2268985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2269985db425SBarry Smith   PetscFunctionReturn(0);
2270985db425SBarry Smith }
2271985db425SBarry Smith 
2272e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2273985db425SBarry Smith {
2274985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2275985db425SBarry Smith   PetscErrorCode ierr;
2276d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
2277985db425SBarry Smith   PetscScalar    *x;
2278985db425SBarry Smith   PetscReal      atmp;
2279985db425SBarry Smith   MatScalar      *aa = a->v;
2280985db425SBarry Smith 
2281985db425SBarry Smith   PetscFunctionBegin;
2282e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2283985db425SBarry Smith 
2284985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2285985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2286985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2287e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2288985db425SBarry Smith   for (i=0; i<m; i++) {
22899189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2290985db425SBarry Smith     for (j=1; j<n; j++) {
2291985db425SBarry Smith       atmp = PetscAbsScalar(aa[i+m*j]);
2292985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2293985db425SBarry Smith     }
2294985db425SBarry Smith   }
2295985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2296985db425SBarry Smith   PetscFunctionReturn(0);
2297985db425SBarry Smith }
2298985db425SBarry Smith 
2299e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2300985db425SBarry Smith {
2301985db425SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2302985db425SBarry Smith   PetscErrorCode ierr;
2303d0f46423SBarry Smith   PetscInt       i,j,m = A->rmap->n,n = A->cmap->n,p;
2304985db425SBarry Smith   PetscScalar    *x;
2305985db425SBarry Smith   MatScalar      *aa = a->v;
2306985db425SBarry Smith 
2307985db425SBarry Smith   PetscFunctionBegin;
2308e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2309985db425SBarry Smith 
2310985db425SBarry Smith   ierr = VecSet(v,0.0);CHKERRQ(ierr);
2311985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2312985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2313e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2314985db425SBarry Smith   for (i=0; i<m; i++) {
2315985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2316985db425SBarry Smith     for (j=1; j<n; j++) {
2317985db425SBarry Smith       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;}
2318985db425SBarry Smith     }
2319985db425SBarry Smith   }
2320985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2321985db425SBarry Smith   PetscFunctionReturn(0);
2322985db425SBarry Smith }
2323985db425SBarry Smith 
2324e0877f53SBarry Smith static PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
23258d0534beSBarry Smith {
23268d0534beSBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
23278d0534beSBarry Smith   PetscErrorCode ierr;
23288d0534beSBarry Smith   PetscScalar    *x;
23298d0534beSBarry Smith 
23308d0534beSBarry Smith   PetscFunctionBegin;
2331e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
23328d0534beSBarry Smith 
23338d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2334580bdb30SBarry Smith   ierr = PetscArraycpy(x,a->v+col*a->lda,A->rmap->n);CHKERRQ(ierr);
23358d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
23368d0534beSBarry Smith   PetscFunctionReturn(0);
23378d0534beSBarry Smith }
23388d0534beSBarry Smith 
23390716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
23400716a85fSBarry Smith {
23410716a85fSBarry Smith   PetscErrorCode    ierr;
23420716a85fSBarry Smith   PetscInt          i,j,m,n;
23431683a169SBarry Smith   const PetscScalar *a;
23440716a85fSBarry Smith 
23450716a85fSBarry Smith   PetscFunctionBegin;
23460716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2347580bdb30SBarry Smith   ierr = PetscArrayzero(norms,n);CHKERRQ(ierr);
23481683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&a);CHKERRQ(ierr);
23490716a85fSBarry Smith   if (type == NORM_2) {
23500716a85fSBarry Smith     for (i=0; i<n; i++) {
23510716a85fSBarry Smith       for (j=0; j<m; j++) {
23520716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
23530716a85fSBarry Smith       }
23540716a85fSBarry Smith       a += m;
23550716a85fSBarry Smith     }
23560716a85fSBarry Smith   } else if (type == NORM_1) {
23570716a85fSBarry Smith     for (i=0; i<n; i++) {
23580716a85fSBarry Smith       for (j=0; j<m; j++) {
23590716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
23600716a85fSBarry Smith       }
23610716a85fSBarry Smith       a += m;
23620716a85fSBarry Smith     }
23630716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
23640716a85fSBarry Smith     for (i=0; i<n; i++) {
23650716a85fSBarry Smith       for (j=0; j<m; j++) {
23660716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
23670716a85fSBarry Smith       }
23680716a85fSBarry Smith       a += m;
23690716a85fSBarry Smith     }
2370ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
23711683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&a);CHKERRQ(ierr);
23720716a85fSBarry Smith   if (type == NORM_2) {
23738f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
23740716a85fSBarry Smith   }
23750716a85fSBarry Smith   PetscFunctionReturn(0);
23760716a85fSBarry Smith }
23770716a85fSBarry Smith 
237873a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
237973a71a0fSBarry Smith {
238073a71a0fSBarry Smith   PetscErrorCode ierr;
238173a71a0fSBarry Smith   PetscScalar    *a;
238273a71a0fSBarry Smith   PetscInt       m,n,i;
238373a71a0fSBarry Smith 
238473a71a0fSBarry Smith   PetscFunctionBegin;
238573a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
23868c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
238773a71a0fSBarry Smith   for (i=0; i<m*n; i++) {
238873a71a0fSBarry Smith     ierr = PetscRandomGetValue(rctx,a+i);CHKERRQ(ierr);
238973a71a0fSBarry Smith   }
23908c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
239173a71a0fSBarry Smith   PetscFunctionReturn(0);
239273a71a0fSBarry Smith }
239373a71a0fSBarry Smith 
23943b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
23953b49f96aSBarry Smith {
23963b49f96aSBarry Smith   PetscFunctionBegin;
23973b49f96aSBarry Smith   *missing = PETSC_FALSE;
23983b49f96aSBarry Smith   PetscFunctionReturn(0);
23993b49f96aSBarry Smith }
240073a71a0fSBarry Smith 
2401af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
240286aefd0dSHong Zhang {
240386aefd0dSHong Zhang   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
240486aefd0dSHong Zhang 
240586aefd0dSHong Zhang   PetscFunctionBegin;
240686aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
240786aefd0dSHong Zhang   *vals = a->v+col*a->lda;
240886aefd0dSHong Zhang   PetscFunctionReturn(0);
240986aefd0dSHong Zhang }
241086aefd0dSHong Zhang 
2411af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
241286aefd0dSHong Zhang {
241386aefd0dSHong Zhang   PetscFunctionBegin;
241486aefd0dSHong Zhang   *vals = 0; /* user cannot accidently use the array later */
241586aefd0dSHong Zhang   PetscFunctionReturn(0);
241686aefd0dSHong Zhang }
2417abc3b08eSStefano Zampini 
2418289bc588SBarry Smith /* -------------------------------------------------------------------*/
2419a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2420905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2421905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2422905e6a2fSBarry Smith                                         MatMult_SeqDense,
242397304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
24247c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
24257c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2426db4efbfdSBarry Smith                                         0,
2427db4efbfdSBarry Smith                                         0,
2428db4efbfdSBarry Smith                                         0,
2429db4efbfdSBarry Smith                                 /* 10*/ 0,
2430905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2431905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
243241f059aeSBarry Smith                                         MatSOR_SeqDense,
2433ec8511deSBarry Smith                                         MatTranspose_SeqDense,
243497304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2435905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2436905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2437905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2438905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2439c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2440c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2441905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2442905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2443d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2444db4efbfdSBarry Smith                                         0,
2445db4efbfdSBarry Smith                                         0,
2446db4efbfdSBarry Smith                                         0,
2447db4efbfdSBarry Smith                                         0,
24484994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2449273d9f13SBarry Smith                                         0,
2450905e6a2fSBarry Smith                                         0,
245173a71a0fSBarry Smith                                         0,
245273a71a0fSBarry Smith                                         0,
2453d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2454a5ae1ecdSBarry Smith                                         0,
2455a5ae1ecdSBarry Smith                                         0,
2456a5ae1ecdSBarry Smith                                         0,
2457a5ae1ecdSBarry Smith                                         0,
2458d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
24597dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2460a5ae1ecdSBarry Smith                                         0,
24614b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2462a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2463d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2464a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
24657d68702bSBarry Smith                                         MatShift_Basic,
2466a5ae1ecdSBarry Smith                                         0,
24673f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
246873a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2469a5ae1ecdSBarry Smith                                         0,
2470a5ae1ecdSBarry Smith                                         0,
2471a5ae1ecdSBarry Smith                                         0,
2472a5ae1ecdSBarry Smith                                         0,
2473d519adbfSMatthew Knepley                                 /* 54*/ 0,
2474a5ae1ecdSBarry Smith                                         0,
2475a5ae1ecdSBarry Smith                                         0,
2476a5ae1ecdSBarry Smith                                         0,
2477a5ae1ecdSBarry Smith                                         0,
2478d519adbfSMatthew Knepley                                 /* 59*/ 0,
2479e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2480e03a110bSBarry Smith                                         MatView_SeqDense,
2481357abbc8SBarry Smith                                         0,
248297304618SKris Buschelman                                         0,
2483d519adbfSMatthew Knepley                                 /* 64*/ 0,
248497304618SKris Buschelman                                         0,
248597304618SKris Buschelman                                         0,
248697304618SKris Buschelman                                         0,
248797304618SKris Buschelman                                         0,
2488d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
248997304618SKris Buschelman                                         0,
249097304618SKris Buschelman                                         0,
249197304618SKris Buschelman                                         0,
249297304618SKris Buschelman                                         0,
2493d519adbfSMatthew Knepley                                 /* 74*/ 0,
249497304618SKris Buschelman                                         0,
249597304618SKris Buschelman                                         0,
249697304618SKris Buschelman                                         0,
249797304618SKris Buschelman                                         0,
2498d519adbfSMatthew Knepley                                 /* 79*/ 0,
249997304618SKris Buschelman                                         0,
250097304618SKris Buschelman                                         0,
250197304618SKris Buschelman                                         0,
25025bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2503865e5f61SKris Buschelman                                         0,
25041cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2505865e5f61SKris Buschelman                                         0,
2506865e5f61SKris Buschelman                                         0,
2507865e5f61SKris Buschelman                                         0,
2508d519adbfSMatthew Knepley                                 /* 89*/ MatMatMult_SeqDense_SeqDense,
2509a9fe9ddaSSatish Balay                                         MatMatMultSymbolic_SeqDense_SeqDense,
2510a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2511abc3b08eSStefano Zampini                                         MatPtAP_SeqDense_SeqDense,
2512abc3b08eSStefano Zampini                                         MatPtAPSymbolic_SeqDense_SeqDense,
2513abc3b08eSStefano Zampini                                 /* 94*/ MatPtAPNumeric_SeqDense_SeqDense,
251469f65d41SStefano Zampini                                         MatMatTransposeMult_SeqDense_SeqDense,
251569f65d41SStefano Zampini                                         MatMatTransposeMultSymbolic_SeqDense_SeqDense,
251669f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2517284134d9SBarry Smith                                         0,
2518d519adbfSMatthew Knepley                                 /* 99*/ 0,
2519284134d9SBarry Smith                                         0,
2520284134d9SBarry Smith                                         0,
2521ba337c44SJed Brown                                         MatConjugate_SeqDense,
2522f73d5cc4SBarry Smith                                         0,
2523ba337c44SJed Brown                                 /*104*/ 0,
2524ba337c44SJed Brown                                         MatRealPart_SeqDense,
2525ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2526985db425SBarry Smith                                         0,
2527985db425SBarry Smith                                         0,
25288208b9aeSStefano Zampini                                 /*109*/ 0,
2529985db425SBarry Smith                                         0,
25308d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2531aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
25323b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2533aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2534aabbc4fbSShri Abhyankar                                         0,
2535aabbc4fbSShri Abhyankar                                         0,
2536aabbc4fbSShri Abhyankar                                         0,
2537aabbc4fbSShri Abhyankar                                         0,
2538aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2539aabbc4fbSShri Abhyankar                                         0,
2540aabbc4fbSShri Abhyankar                                         0,
25410716a85fSBarry Smith                                         0,
25420716a85fSBarry Smith                                         0,
25430716a85fSBarry Smith                                 /*124*/ 0,
25445df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
25455df89d91SHong Zhang                                         0,
25465df89d91SHong Zhang                                         0,
25475df89d91SHong Zhang                                         0,
25485df89d91SHong Zhang                                 /*129*/ 0,
254975648e8dSHong Zhang                                         MatTransposeMatMult_SeqDense_SeqDense,
255075648e8dSHong Zhang                                         MatTransposeMatMultSymbolic_SeqDense_SeqDense,
255175648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
25523964eb88SJed Brown                                         0,
25533964eb88SJed Brown                                 /*134*/ 0,
25543964eb88SJed Brown                                         0,
25553964eb88SJed Brown                                         0,
25563964eb88SJed Brown                                         0,
25573964eb88SJed Brown                                         0,
25583964eb88SJed Brown                                 /*139*/ 0,
2559f9426fe0SMark Adams                                         0,
2560d528f656SJakub Kruzik                                         0,
2561d528f656SJakub Kruzik                                         0,
2562d528f656SJakub Kruzik                                         0,
2563d528f656SJakub Kruzik                                 /*144*/ MatCreateMPIMatConcatenateSeqMat_SeqDense
2564985db425SBarry Smith };
256590ace30eSBarry Smith 
25664b828684SBarry Smith /*@C
2567fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2568d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2569d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2570289bc588SBarry Smith 
2571d083f849SBarry Smith    Collective
2572db81eaa0SLois Curfman McInnes 
257320563c6bSBarry Smith    Input Parameters:
2574db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
25750c775827SLois Curfman McInnes .  m - number of rows
257618f449edSLois Curfman McInnes .  n - number of columns
25770298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2578dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
257920563c6bSBarry Smith 
258020563c6bSBarry Smith    Output Parameter:
258144cd7ae7SLois Curfman McInnes .  A - the matrix
258220563c6bSBarry Smith 
2583b259b22eSLois Curfman McInnes    Notes:
258418f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
258518f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
25860298fd71SBarry Smith    set data=NULL.
258718f449edSLois Curfman McInnes 
2588027ccd11SLois Curfman McInnes    Level: intermediate
2589027ccd11SLois Curfman McInnes 
259069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
259120563c6bSBarry Smith @*/
25927087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2593289bc588SBarry Smith {
2594dfbe8321SBarry Smith   PetscErrorCode ierr;
25953b2fbd54SBarry Smith 
25963a40ed3dSBarry Smith   PetscFunctionBegin;
2597f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2598f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2599273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2600273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2601273d9f13SBarry Smith   PetscFunctionReturn(0);
2602273d9f13SBarry Smith }
2603273d9f13SBarry Smith 
2604273d9f13SBarry Smith /*@C
2605273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2606273d9f13SBarry Smith 
2607d083f849SBarry Smith    Collective
2608273d9f13SBarry Smith 
2609273d9f13SBarry Smith    Input Parameters:
26101c4f3114SJed Brown +  B - the matrix
26110298fd71SBarry Smith -  data - the array (or NULL)
2612273d9f13SBarry Smith 
2613273d9f13SBarry Smith    Notes:
2614273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2615273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2616284134d9SBarry Smith    need not call this routine.
2617273d9f13SBarry Smith 
2618273d9f13SBarry Smith    Level: intermediate
2619273d9f13SBarry Smith 
262069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA()
2621867c911aSBarry Smith 
2622273d9f13SBarry Smith @*/
26237087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2624273d9f13SBarry Smith {
26254ac538c5SBarry Smith   PetscErrorCode ierr;
2626a23d5eceSKris Buschelman 
2627a23d5eceSKris Buschelman   PetscFunctionBegin;
26284ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2629a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2630a23d5eceSKris Buschelman }
2631a23d5eceSKris Buschelman 
26327087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2633a23d5eceSKris Buschelman {
2634273d9f13SBarry Smith   Mat_SeqDense   *b;
2635dfbe8321SBarry Smith   PetscErrorCode ierr;
2636273d9f13SBarry Smith 
2637273d9f13SBarry Smith   PetscFunctionBegin;
2638273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2639a868139aSShri Abhyankar 
264034ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
264134ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
264234ef9618SShri Abhyankar 
2643273d9f13SBarry Smith   b       = (Mat_SeqDense*)B->data;
264486d161a7SShri Abhyankar   b->Mmax = B->rmap->n;
264586d161a7SShri Abhyankar   b->Nmax = B->cmap->n;
264686d161a7SShri Abhyankar   if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n;
264786d161a7SShri Abhyankar 
2648220afb94SBarry Smith   ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr);
26499e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
26509e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2651e92229d0SSatish Balay     ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr);
26523bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr);
26532205254eSKarl Rupp 
26549e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2655273d9f13SBarry Smith   } else { /* user-allocated storage */
26569e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2657273d9f13SBarry Smith     b->v          = data;
2658273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2659273d9f13SBarry Smith   }
26600450473dSBarry Smith   B->assembled = PETSC_TRUE;
2661273d9f13SBarry Smith   PetscFunctionReturn(0);
2662273d9f13SBarry Smith }
2663273d9f13SBarry Smith 
266465b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2665cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
26668baccfbdSHong Zhang {
2667d77f618aSHong Zhang   Mat               mat_elemental;
2668d77f618aSHong Zhang   PetscErrorCode    ierr;
26691683a169SBarry Smith   const PetscScalar *array;
26701683a169SBarry Smith   PetscScalar       *v_colwise;
2671d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2672d77f618aSHong Zhang 
26738baccfbdSHong Zhang   PetscFunctionBegin;
2674d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
26751683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&array);CHKERRQ(ierr);
2676d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2677d77f618aSHong Zhang   k = 0;
2678d77f618aSHong Zhang   for (j=0; j<N; j++) {
2679d77f618aSHong Zhang     cols[j] = j;
2680d77f618aSHong Zhang     for (i=0; i<M; i++) {
2681d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2682d77f618aSHong Zhang     }
2683d77f618aSHong Zhang   }
2684d77f618aSHong Zhang   for (i=0; i<M; i++) {
2685d77f618aSHong Zhang     rows[i] = i;
2686d77f618aSHong Zhang   }
26871683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&array);CHKERRQ(ierr);
2688d77f618aSHong Zhang 
2689d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2690d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2691d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2692d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2693d77f618aSHong Zhang 
2694d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2695d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2696d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2697d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2698d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2699d77f618aSHong Zhang 
2700511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
270128be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2702d77f618aSHong Zhang   } else {
2703d77f618aSHong Zhang     *newmat = mat_elemental;
2704d77f618aSHong Zhang   }
27058baccfbdSHong Zhang   PetscFunctionReturn(0);
27068baccfbdSHong Zhang }
270765b80a83SHong Zhang #endif
27088baccfbdSHong Zhang 
27091b807ce4Svictorle /*@C
27101b807ce4Svictorle   MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array
27111b807ce4Svictorle 
27121b807ce4Svictorle   Input parameter:
27131b807ce4Svictorle + A - the matrix
27141b807ce4Svictorle - lda - the leading dimension
27151b807ce4Svictorle 
27161b807ce4Svictorle   Notes:
2717867c911aSBarry Smith   This routine is to be used in conjunction with MatSeqDenseSetPreallocation();
27181b807ce4Svictorle   it asserts that the preallocation has a leading dimension (the LDA parameter
27191b807ce4Svictorle   of Blas and Lapack fame) larger than M, the first dimension of the matrix.
27201b807ce4Svictorle 
27211b807ce4Svictorle   Level: intermediate
27221b807ce4Svictorle 
2723284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize()
2724867c911aSBarry Smith 
27251b807ce4Svictorle @*/
27267087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetLDA(Mat B,PetscInt lda)
27271b807ce4Svictorle {
27281b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
272921a2c019SBarry Smith 
27301b807ce4Svictorle   PetscFunctionBegin;
2731e32f2f54SBarry 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);
27321b807ce4Svictorle   b->lda       = lda;
273321a2c019SBarry Smith   b->changelda = PETSC_FALSE;
273421a2c019SBarry Smith   b->Mmax      = PetscMax(b->Mmax,lda);
27351b807ce4Svictorle   PetscFunctionReturn(0);
27361b807ce4Svictorle }
27371b807ce4Svictorle 
2738d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
2739d528f656SJakub Kruzik {
2740d528f656SJakub Kruzik   PetscErrorCode ierr;
2741d528f656SJakub Kruzik   PetscMPIInt    size;
2742d528f656SJakub Kruzik 
2743d528f656SJakub Kruzik   PetscFunctionBegin;
2744d528f656SJakub Kruzik   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2745d528f656SJakub Kruzik   if (size == 1) {
2746d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
2747d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
2748d528f656SJakub Kruzik     } else {
2749d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2750d528f656SJakub Kruzik     }
2751d528f656SJakub Kruzik   } else {
2752d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
2753d528f656SJakub Kruzik   }
2754d528f656SJakub Kruzik   PetscFunctionReturn(0);
2755d528f656SJakub Kruzik }
2756d528f656SJakub Kruzik 
27570bad9183SKris Buschelman /*MC
2758fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
27590bad9183SKris Buschelman 
27600bad9183SKris Buschelman    Options Database Keys:
27610bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
27620bad9183SKris Buschelman 
27630bad9183SKris Buschelman   Level: beginner
27640bad9183SKris Buschelman 
276589665df3SBarry Smith .seealso: MatCreateSeqDense()
276689665df3SBarry Smith 
27670bad9183SKris Buschelman M*/
27680bad9183SKris Buschelman 
27698cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqDense(Mat B)
2770273d9f13SBarry Smith {
2771273d9f13SBarry Smith   Mat_SeqDense   *b;
2772dfbe8321SBarry Smith   PetscErrorCode ierr;
27737c334f02SBarry Smith   PetscMPIInt    size;
2774273d9f13SBarry Smith 
2775273d9f13SBarry Smith   PetscFunctionBegin;
2776ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
2777e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
277855659b69SBarry Smith 
2779b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
2780549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
278144cd7ae7SLois Curfman McInnes   B->data = (void*)b;
278218f449edSLois Curfman McInnes 
2783273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
27844e220ebcSLois Curfman McInnes 
278549a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
2786bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
27878572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2788d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
2789d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
27908572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
2791715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
2792bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
27938baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
27948baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
27958baccfbdSHong Zhang #endif
2796bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
2797bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaij_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2798bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2799bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2800*a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqbaij_seqdense_C",MatMatMult_SeqBAIJ_SeqDense);CHKERRQ(ierr);
2801*a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqbaij_seqdense_C",MatMatMultSymbolic_SeqBAIJ_SeqDense);CHKERRQ(ierr);
2802*a001520aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqbaij_seqdense_C",MatMatMultNumeric_SeqBAIJ_SeqDense);CHKERRQ(ierr);
2803abc3b08eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaij_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
28044099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijperm_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
28054099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijperm_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28064099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijperm_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
28074099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijperm_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
2808e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijsell_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2809e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijsell_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2810e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijsell_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2811e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijsell_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
281296e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaijmkl_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
281396e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaijmkl_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
281496e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaijmkl_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
281596e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaijmkl_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr);
281696e6d5c4SRichard Tran Mills 
28173bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaij_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
28183bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28193bf78175SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
28204099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijperm_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
28214099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijperm_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
28224099cc6bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijperm_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2823e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijsell_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
2824e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijsell_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
2825e9e4f4a6SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijsell_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
282696e6d5c4SRichard Tran Mills 
282796e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaijmkl_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr);
282896e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaijmkl_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr);
282996e6d5c4SRichard Tran Mills   ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaijmkl_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr);
2830af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
2831af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
283217667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
28333a40ed3dSBarry Smith   PetscFunctionReturn(0);
2834289bc588SBarry Smith }
283586aefd0dSHong Zhang 
283686aefd0dSHong Zhang /*@C
2837af53bab2SHong 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.
283886aefd0dSHong Zhang 
283986aefd0dSHong Zhang    Not Collective
284086aefd0dSHong Zhang 
284186aefd0dSHong Zhang    Input Parameter:
284286aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
284386aefd0dSHong Zhang -  col - column index
284486aefd0dSHong Zhang 
284586aefd0dSHong Zhang    Output Parameter:
284686aefd0dSHong Zhang .  vals - pointer to the data
284786aefd0dSHong Zhang 
284886aefd0dSHong Zhang    Level: intermediate
284986aefd0dSHong Zhang 
285086aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
285186aefd0dSHong Zhang @*/
285286aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
285386aefd0dSHong Zhang {
285486aefd0dSHong Zhang   PetscErrorCode ierr;
285586aefd0dSHong Zhang 
285686aefd0dSHong Zhang   PetscFunctionBegin;
285786aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
285886aefd0dSHong Zhang   PetscFunctionReturn(0);
285986aefd0dSHong Zhang }
286086aefd0dSHong Zhang 
286186aefd0dSHong Zhang /*@C
286286aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
286386aefd0dSHong Zhang 
286486aefd0dSHong Zhang    Not Collective
286586aefd0dSHong Zhang 
286686aefd0dSHong Zhang    Input Parameter:
286786aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
286886aefd0dSHong Zhang 
286986aefd0dSHong Zhang    Output Parameter:
287086aefd0dSHong Zhang .  vals - pointer to the data
287186aefd0dSHong Zhang 
287286aefd0dSHong Zhang    Level: intermediate
287386aefd0dSHong Zhang 
287486aefd0dSHong Zhang .seealso: MatDenseGetColumn()
287586aefd0dSHong Zhang @*/
287686aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
287786aefd0dSHong Zhang {
287886aefd0dSHong Zhang   PetscErrorCode ierr;
287986aefd0dSHong Zhang 
288086aefd0dSHong Zhang   PetscFunctionBegin;
288186aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
288286aefd0dSHong Zhang   PetscFunctionReturn(0);
288386aefd0dSHong Zhang }
2884