xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 4905a7bc61a644ac28a555b575668251734ce1fa)
1be1d678aSKris Buschelman 
267e560aaSBarry Smith /*
367e560aaSBarry Smith      Defines the basic matrix operations for sequential dense.
467e560aaSBarry Smith */
5289bc588SBarry Smith 
6dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/
7c6db04a5SJed Brown #include <petscblaslapack.h>
8289bc588SBarry Smith 
96a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h>
10b2573a8aSBarry Smith 
11ca15aa20SStefano Zampini PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian)
128c178816SStefano Zampini {
138c178816SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
148c178816SStefano Zampini   PetscInt       j, k, n = A->rmap->n;
15ca15aa20SStefano Zampini   PetscScalar    *v;
16ca15aa20SStefano Zampini   PetscErrorCode ierr;
178c178816SStefano Zampini 
188c178816SStefano Zampini   PetscFunctionBegin;
198c178816SStefano Zampini   if (A->rmap->n != A->cmap->n) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot symmetrize a rectangular matrix");
20ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
218c178816SStefano Zampini   if (!hermitian) {
228c178816SStefano Zampini     for (k=0;k<n;k++) {
238c178816SStefano Zampini       for (j=k;j<n;j++) {
24ca15aa20SStefano Zampini         v[j*mat->lda + k] = v[k*mat->lda + j];
258c178816SStefano Zampini       }
268c178816SStefano Zampini     }
278c178816SStefano Zampini   } else {
288c178816SStefano Zampini     for (k=0;k<n;k++) {
298c178816SStefano Zampini       for (j=k;j<n;j++) {
30ca15aa20SStefano Zampini         v[j*mat->lda + k] = PetscConj(v[k*mat->lda + j]);
318c178816SStefano Zampini       }
328c178816SStefano Zampini     }
338c178816SStefano Zampini   }
34ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
358c178816SStefano Zampini   PetscFunctionReturn(0);
368c178816SStefano Zampini }
378c178816SStefano Zampini 
3805709791SSatish Balay PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A)
398c178816SStefano Zampini {
408c178816SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
418c178816SStefano Zampini   PetscErrorCode ierr;
428c178816SStefano Zampini   PetscBLASInt   info,n;
438c178816SStefano Zampini 
448c178816SStefano Zampini   PetscFunctionBegin;
458c178816SStefano Zampini   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
468c178816SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
478c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
488c178816SStefano Zampini     if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
498c178816SStefano Zampini     if (!mat->fwork) {
508c178816SStefano Zampini       mat->lfwork = n;
518c178816SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
528c178816SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
538c178816SStefano Zampini     }
5400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
558c178816SStefano Zampini     PetscStackCallBLAS("LAPACKgetri",LAPACKgetri_(&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
5600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
57ca15aa20SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
588c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
598c178816SStefano Zampini     if (A->spd) {
6000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
618c178816SStefano Zampini       PetscStackCallBLAS("LAPACKpotri",LAPACKpotri_("L",&n,mat->v,&mat->lda,&info));
6200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
638c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
648c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
658c178816SStefano Zampini     } else if (A->hermitian) {
668c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
678c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
6800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
698c178816SStefano Zampini       PetscStackCallBLAS("LAPACKhetri",LAPACKhetri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
7000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
718c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
728c178816SStefano Zampini #endif
738c178816SStefano Zampini     } else { /* symmetric case */
748c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
758c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
7600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
778c178816SStefano Zampini       PetscStackCallBLAS("LAPACKsytri",LAPACKsytri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
7800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
798c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_FALSE);CHKERRQ(ierr);
808c178816SStefano Zampini     }
818c178816SStefano Zampini     if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad Inversion: zero pivot in row %D",(PetscInt)info-1);
82ca15aa20SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
838c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
848c178816SStefano Zampini 
858c178816SStefano Zampini   A->ops->solve             = NULL;
868c178816SStefano Zampini   A->ops->matsolve          = NULL;
878c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
888c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
898c178816SStefano Zampini   A->ops->solveadd          = NULL;
908c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
918c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
928c178816SStefano Zampini   ierr                      = PetscFree(A->solvertype);CHKERRQ(ierr);
938c178816SStefano Zampini   PetscFunctionReturn(0);
948c178816SStefano Zampini }
958c178816SStefano Zampini 
963f49a652SStefano Zampini PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
973f49a652SStefano Zampini {
983f49a652SStefano Zampini   PetscErrorCode    ierr;
993f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1003f49a652SStefano Zampini   PetscInt          m  = l->lda, n = A->cmap->n,r = A->rmap->n, i,j;
101ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
1023f49a652SStefano Zampini   const PetscScalar *xx;
1033f49a652SStefano Zampini 
1043f49a652SStefano Zampini   PetscFunctionBegin;
10576bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1063f49a652SStefano Zampini     for (i=0; i<N; i++) {
1073f49a652SStefano Zampini       if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1083f49a652SStefano Zampini       if (rows[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D requested to be zeroed greater than or equal number of rows %D",rows[i],A->rmap->n);
1093f49a652SStefano Zampini       if (rows[i] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Col %D requested to be zeroed greater than or equal number of cols %D",rows[i],A->cmap->n);
1103f49a652SStefano Zampini     }
11176bd3646SJed Brown   }
112ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1133f49a652SStefano Zampini 
1143f49a652SStefano Zampini   /* fix right hand side if needed */
1153f49a652SStefano Zampini   if (x && b) {
1166c4d906cSStefano Zampini     Vec xt;
1176c4d906cSStefano Zampini 
1186c4d906cSStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1196c4d906cSStefano Zampini     ierr = VecDuplicate(x,&xt);CHKERRQ(ierr);
1206c4d906cSStefano Zampini     ierr = VecCopy(x,xt);CHKERRQ(ierr);
1216c4d906cSStefano Zampini     ierr = VecScale(xt,-1.0);CHKERRQ(ierr);
1226c4d906cSStefano Zampini     ierr = MatMultAdd(A,xt,b,b);CHKERRQ(ierr);
1236c4d906cSStefano Zampini     ierr = VecDestroy(&xt);CHKERRQ(ierr);
1243f49a652SStefano Zampini     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1253f49a652SStefano Zampini     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
1263f49a652SStefano Zampini     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
1273f49a652SStefano Zampini     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1283f49a652SStefano Zampini     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
1293f49a652SStefano Zampini   }
1303f49a652SStefano Zampini 
131ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1323f49a652SStefano Zampini   for (i=0; i<N; i++) {
133ca15aa20SStefano Zampini     slot = v + rows[i]*m;
134580bdb30SBarry Smith     ierr = PetscArrayzero(slot,r);CHKERRQ(ierr);
1353f49a652SStefano Zampini   }
1363f49a652SStefano Zampini   for (i=0; i<N; i++) {
137ca15aa20SStefano Zampini     slot = v + rows[i];
1383f49a652SStefano Zampini     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
1393f49a652SStefano Zampini   }
1403f49a652SStefano Zampini   if (diag != 0.0) {
1413f49a652SStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1423f49a652SStefano Zampini     for (i=0; i<N; i++) {
143ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1443f49a652SStefano Zampini       *slot = diag;
1453f49a652SStefano Zampini     }
1463f49a652SStefano Zampini   }
147ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
1483f49a652SStefano Zampini   PetscFunctionReturn(0);
1493f49a652SStefano Zampini }
1503f49a652SStefano Zampini 
151abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C)
152abc3b08eSStefano Zampini {
153abc3b08eSStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)(C->data);
154abc3b08eSStefano Zampini   PetscErrorCode ierr;
155abc3b08eSStefano Zampini 
156abc3b08eSStefano Zampini   PetscFunctionBegin;
157ca15aa20SStefano Zampini   if (c->ptapwork) {
158ca15aa20SStefano Zampini     ierr = (*C->ops->matmultnumeric)(A,P,c->ptapwork);CHKERRQ(ierr);
159ca15aa20SStefano Zampini     ierr = (*C->ops->transposematmultnumeric)(P,c->ptapwork,C);CHKERRQ(ierr);
1604222ddf1SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"Must call MatPtAPSymbolic_SeqDense_SeqDense() first");
161abc3b08eSStefano Zampini   PetscFunctionReturn(0);
162abc3b08eSStefano Zampini }
163abc3b08eSStefano Zampini 
1644222ddf1SHong Zhang PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat C)
165abc3b08eSStefano Zampini {
166abc3b08eSStefano Zampini   Mat_SeqDense   *c;
1677a3c3d58SStefano Zampini   PetscBool      cisdense;
168abc3b08eSStefano Zampini   PetscErrorCode ierr;
169abc3b08eSStefano Zampini 
170abc3b08eSStefano Zampini   PetscFunctionBegin;
1714222ddf1SHong Zhang   ierr = MatSetSizes(C,P->cmap->n,P->cmap->n,P->cmap->N,P->cmap->N);CHKERRQ(ierr);
1727a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
1737a3c3d58SStefano Zampini   if (!cisdense) {
1747a3c3d58SStefano Zampini     PetscBool flg;
1757a3c3d58SStefano Zampini 
1767a3c3d58SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)P,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
1774222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
1787a3c3d58SStefano Zampini   }
1797a3c3d58SStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
1804222ddf1SHong Zhang   c    = (Mat_SeqDense*)C->data;
181ca15aa20SStefano Zampini   ierr = MatCreate(PetscObjectComm((PetscObject)A),&c->ptapwork);CHKERRQ(ierr);
182ca15aa20SStefano Zampini   ierr = MatSetSizes(c->ptapwork,A->rmap->n,P->cmap->n,A->rmap->N,P->cmap->N);CHKERRQ(ierr);
1837a3c3d58SStefano Zampini   ierr = MatSetType(c->ptapwork,((PetscObject)C)->type_name);CHKERRQ(ierr);
1847a3c3d58SStefano Zampini   ierr = MatSetUp(c->ptapwork);CHKERRQ(ierr);
185abc3b08eSStefano Zampini   PetscFunctionReturn(0);
186abc3b08eSStefano Zampini }
187abc3b08eSStefano Zampini 
188cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
189b49cda9fSStefano Zampini {
190a13144ffSStefano Zampini   Mat             B = NULL;
191b49cda9fSStefano Zampini   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
192b49cda9fSStefano Zampini   Mat_SeqDense    *b;
193b49cda9fSStefano Zampini   PetscErrorCode  ierr;
194b49cda9fSStefano Zampini   PetscInt        *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i;
1952e5835c6SStefano Zampini   const MatScalar *av;
196a13144ffSStefano Zampini   PetscBool       isseqdense;
197b49cda9fSStefano Zampini 
198b49cda9fSStefano Zampini   PetscFunctionBegin;
199a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
200a13144ffSStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense);CHKERRQ(ierr);
201a32993e3SJed Brown     if (!isseqdense) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type_name);
202a13144ffSStefano Zampini   }
203a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
204b49cda9fSStefano Zampini     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
205b49cda9fSStefano Zampini     ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
206b49cda9fSStefano Zampini     ierr = MatSetType(B,MATSEQDENSE);CHKERRQ(ierr);
207b49cda9fSStefano Zampini     ierr = MatSeqDenseSetPreallocation(B,NULL);CHKERRQ(ierr);
208b49cda9fSStefano Zampini     b    = (Mat_SeqDense*)(B->data);
209a13144ffSStefano Zampini   } else {
210a13144ffSStefano Zampini     b    = (Mat_SeqDense*)((*newmat)->data);
211580bdb30SBarry Smith     ierr = PetscArrayzero(b->v,m*n);CHKERRQ(ierr);
212a13144ffSStefano Zampini   }
2132e5835c6SStefano Zampini   ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr);
214b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
215b49cda9fSStefano Zampini     PetscInt j;
216b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
217b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
218b49cda9fSStefano Zampini       aj++;
219b49cda9fSStefano Zampini       av++;
220b49cda9fSStefano Zampini     }
221b49cda9fSStefano Zampini     ai++;
222b49cda9fSStefano Zampini   }
2232e5835c6SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr);
224b49cda9fSStefano Zampini 
225511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
226a13144ffSStefano Zampini     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
227a13144ffSStefano Zampini     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22828be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
229b49cda9fSStefano Zampini   } else {
230a13144ffSStefano Zampini     if (B) *newmat = B;
231a13144ffSStefano Zampini     ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
232a13144ffSStefano Zampini     ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
233b49cda9fSStefano Zampini   }
234b49cda9fSStefano Zampini   PetscFunctionReturn(0);
235b49cda9fSStefano Zampini }
236b49cda9fSStefano Zampini 
237cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
2386a63e612SBarry Smith {
2396d4ec7b0SPierre Jolivet   Mat            B = NULL;
2406a63e612SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2416a63e612SBarry Smith   PetscErrorCode ierr;
2429399e1b8SMatthew G. Knepley   PetscInt       i, j;
2439399e1b8SMatthew G. Knepley   PetscInt       *rows, *nnz;
2449399e1b8SMatthew G. Knepley   MatScalar      *aa = a->v, *vals;
2456a63e612SBarry Smith 
2466a63e612SBarry Smith   PetscFunctionBegin;
2476d4ec7b0SPierre Jolivet   ierr = PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals);CHKERRQ(ierr);
2486d4ec7b0SPierre Jolivet   if (reuse != MAT_REUSE_MATRIX) {
249ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
2506a63e612SBarry Smith     ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
2516a63e612SBarry Smith     ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
2529399e1b8SMatthew G. Knepley     for (j=0; j<A->cmap->n; j++) {
2536d4ec7b0SPierre Jolivet       for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i];
2546a63e612SBarry Smith       aa += a->lda;
2556a63e612SBarry Smith     }
2569399e1b8SMatthew G. Knepley     ierr = MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz);CHKERRQ(ierr);
2576d4ec7b0SPierre Jolivet   } else B = *newmat;
2589399e1b8SMatthew G. Knepley   aa = a->v;
2599399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2609399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2616d4ec7b0SPierre Jolivet     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) {rows[numRows] = i; vals[numRows++] = aa[i];}
2629399e1b8SMatthew G. Knepley     ierr = MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr);
2639399e1b8SMatthew G. Knepley     aa  += a->lda;
2649399e1b8SMatthew G. Knepley   }
2659399e1b8SMatthew G. Knepley   ierr = PetscFree3(rows,nnz,vals);CHKERRQ(ierr);
2666a63e612SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2676a63e612SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2686a63e612SBarry Smith 
269511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
27028be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
2716d4ec7b0SPierre Jolivet   } else if (reuse != MAT_REUSE_MATRIX) *newmat = B;
2726a63e612SBarry Smith   PetscFunctionReturn(0);
2736a63e612SBarry Smith }
2746a63e612SBarry Smith 
275ca15aa20SStefano Zampini PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
2761987afe7SBarry Smith {
2771987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
278ca15aa20SStefano Zampini   const PetscScalar *xv;
279ca15aa20SStefano Zampini   PetscScalar       *yv;
28023fff9afSBarry Smith   PetscBLASInt      N,m,ldax = 0,lday = 0,one = 1;
281efee365bSSatish Balay   PetscErrorCode    ierr;
2823a40ed3dSBarry Smith 
2833a40ed3dSBarry Smith   PetscFunctionBegin;
284ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(X,&xv);CHKERRQ(ierr);
285ca15aa20SStefano Zampini   ierr = MatDenseGetArray(Y,&yv);CHKERRQ(ierr);
286c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n*X->cmap->n,&N);CHKERRQ(ierr);
287c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n,&m);CHKERRQ(ierr);
288c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->lda,&ldax);CHKERRQ(ierr);
289c5df96a5SBarry Smith   ierr = PetscBLASIntCast(y->lda,&lday);CHKERRQ(ierr);
290a5ce6ee0Svictorle   if (ldax>m || lday>m) {
291ca15aa20SStefano Zampini     PetscInt j;
292ca15aa20SStefano Zampini 
293d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
294ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&alpha,xv+j*ldax,&one,yv+j*lday,&one));
295a5ce6ee0Svictorle     }
296a5ce6ee0Svictorle   } else {
297ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&alpha,xv,&one,yv,&one));
298a5ce6ee0Svictorle   }
299ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(X,&xv);CHKERRQ(ierr);
300ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(Y,&yv);CHKERRQ(ierr);
301ca0c957dSBarry Smith   ierr = PetscLogFlops(PetscMax(2.0*N-1,0));CHKERRQ(ierr);
3023a40ed3dSBarry Smith   PetscFunctionReturn(0);
3031987afe7SBarry Smith }
3041987afe7SBarry Smith 
305e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
306289bc588SBarry Smith {
307ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n*A->cmap->n;
3083a40ed3dSBarry Smith 
3093a40ed3dSBarry Smith   PetscFunctionBegin;
3104e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
311ca15aa20SStefano Zampini   info->nz_allocated      = N;
312ca15aa20SStefano Zampini   info->nz_used           = N;
313ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
314ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
3154e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3167adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3174e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3184e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3194e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3203a40ed3dSBarry Smith   PetscFunctionReturn(0);
321289bc588SBarry Smith }
322289bc588SBarry Smith 
323637a0070SStefano Zampini PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
32480cd9d93SLois Curfman McInnes {
325273d9f13SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
326ca15aa20SStefano Zampini   PetscScalar    *v;
327efee365bSSatish Balay   PetscErrorCode ierr;
32823fff9afSBarry Smith   PetscBLASInt   one = 1,j,nz,lda = 0;
32980cd9d93SLois Curfman McInnes 
3303a40ed3dSBarry Smith   PetscFunctionBegin;
331ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
332c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->lda,&lda);CHKERRQ(ierr);
333d0f46423SBarry Smith   if (lda>A->rmap->n) {
334c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n,&nz);CHKERRQ(ierr);
335d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
336ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v+j*lda,&one));
337a5ce6ee0Svictorle     }
338a5ce6ee0Svictorle   } else {
339c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz);CHKERRQ(ierr);
340ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v,&one));
341a5ce6ee0Svictorle   }
342efee365bSSatish Balay   ierr = PetscLogFlops(nz);CHKERRQ(ierr);
343ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
3443a40ed3dSBarry Smith   PetscFunctionReturn(0);
34580cd9d93SLois Curfman McInnes }
34680cd9d93SLois Curfman McInnes 
347e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3481cbb95d3SBarry Smith {
3491cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
350ca15aa20SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
351ca15aa20SStefano Zampini   const PetscScalar *v;
352ca15aa20SStefano Zampini   PetscErrorCode    ierr;
3531cbb95d3SBarry Smith 
3541cbb95d3SBarry Smith   PetscFunctionBegin;
3551cbb95d3SBarry Smith   *fl = PETSC_FALSE;
356d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
357ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
3581cbb95d3SBarry Smith   for (i=0; i<m; i++) {
359ca15aa20SStefano Zampini     for (j=i; j<m; j++) {
360637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) {
361637a0070SStefano Zampini         goto restore;
3621cbb95d3SBarry Smith       }
3631cbb95d3SBarry Smith     }
364637a0070SStefano Zampini   }
3651cbb95d3SBarry Smith   *fl  = PETSC_TRUE;
366637a0070SStefano Zampini restore:
367637a0070SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
368637a0070SStefano Zampini   PetscFunctionReturn(0);
369637a0070SStefano Zampini }
370637a0070SStefano Zampini 
371637a0070SStefano Zampini static PetscErrorCode MatIsSymmetric_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
372637a0070SStefano Zampini {
373637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
374637a0070SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
375637a0070SStefano Zampini   const PetscScalar *v;
376637a0070SStefano Zampini   PetscErrorCode    ierr;
377637a0070SStefano Zampini 
378637a0070SStefano Zampini   PetscFunctionBegin;
379637a0070SStefano Zampini   *fl = PETSC_FALSE;
380637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
381637a0070SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
382637a0070SStefano Zampini   for (i=0; i<m; i++) {
383637a0070SStefano Zampini     for (j=i; j<m; j++) {
384637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - v[j+i*N]) > rtol) {
385637a0070SStefano Zampini         goto restore;
386637a0070SStefano Zampini       }
387637a0070SStefano Zampini     }
388637a0070SStefano Zampini   }
389637a0070SStefano Zampini   *fl  = PETSC_TRUE;
390637a0070SStefano Zampini restore:
391637a0070SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
3921cbb95d3SBarry Smith   PetscFunctionReturn(0);
3931cbb95d3SBarry Smith }
3941cbb95d3SBarry Smith 
395ca15aa20SStefano Zampini PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
396b24902e0SBarry Smith {
397ca15aa20SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
398b24902e0SBarry Smith   PetscErrorCode ierr;
39923fc5dcaSStefano Zampini   PetscInt       lda = (PetscInt)mat->lda,j,m,nlda = lda;
400b24902e0SBarry Smith 
401b24902e0SBarry Smith   PetscFunctionBegin;
402aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr);
403aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr);
40423fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
40523fc5dcaSStefano Zampini     ierr = MatDenseSetLDA(newi,lda);CHKERRQ(ierr);
40623fc5dcaSStefano Zampini   }
4070298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr);
408b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
409ca15aa20SStefano Zampini     const PetscScalar *av;
410ca15aa20SStefano Zampini     PetscScalar       *v;
411ca15aa20SStefano Zampini 
412ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
413ca15aa20SStefano Zampini     ierr = MatDenseGetArray(newi,&v);CHKERRQ(ierr);
41423fc5dcaSStefano Zampini     ierr = MatDenseGetLDA(newi,&nlda);CHKERRQ(ierr);
415d0f46423SBarry Smith     m    = A->rmap->n;
41623fc5dcaSStefano Zampini     if (lda>m || nlda>m) {
417d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
41823fc5dcaSStefano Zampini         ierr = PetscArraycpy(v+j*nlda,av+j*lda,m);CHKERRQ(ierr);
419b24902e0SBarry Smith       }
420b24902e0SBarry Smith     } else {
421ca15aa20SStefano Zampini       ierr = PetscArraycpy(v,av,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
422b24902e0SBarry Smith     }
423ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(newi,&v);CHKERRQ(ierr);
424ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
425b24902e0SBarry Smith   }
426b24902e0SBarry Smith   PetscFunctionReturn(0);
427b24902e0SBarry Smith }
428b24902e0SBarry Smith 
429ca15aa20SStefano Zampini PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
43002cad45dSBarry Smith {
4316849ba73SBarry Smith   PetscErrorCode ierr;
43202cad45dSBarry Smith 
4333a40ed3dSBarry Smith   PetscFunctionBegin;
434ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr);
435d0f46423SBarry Smith   ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4365c9eb25fSBarry Smith   ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
437719d5645SBarry Smith   ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr);
438b24902e0SBarry Smith   PetscFunctionReturn(0);
439b24902e0SBarry Smith }
440b24902e0SBarry Smith 
441e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
442289bc588SBarry Smith {
4434482741eSBarry Smith   MatFactorInfo  info;
444a093e273SMatthew Knepley   PetscErrorCode ierr;
4453a40ed3dSBarry Smith 
4463a40ed3dSBarry Smith   PetscFunctionBegin;
447c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
448f4259b30SLisandro Dalcin   ierr = (*fact->ops->lufactor)(fact,NULL,NULL,&info);CHKERRQ(ierr);
4493a40ed3dSBarry Smith   PetscFunctionReturn(0);
450289bc588SBarry Smith }
4516ee01492SSatish Balay 
452*4905a7bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal(Mat A, PetscScalar *x, PetscBLASInt xlda, PetscBLASInt nrhs, PetscBLASInt k)
453289bc588SBarry Smith {
454c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
455*4905a7bcSToby Isaac   PetscBLASInt    m, info;
4566849ba73SBarry Smith   PetscErrorCode  ierr;
45767e560aaSBarry Smith 
4583a40ed3dSBarry Smith   PetscFunctionBegin;
459c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
46085e2c93fSHong Zhang   if (A->factortype == MAT_FACTOR_LU) {
46100121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4628b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
46300121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
46485e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
465*4905a7bcSToby Isaac     ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
46685e2c93fSHong Zhang   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
467a49dc2a2SStefano Zampini     if (A->spd) {
46800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4698b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
47000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
47185e2c93fSHong Zhang       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
472a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
473a49dc2a2SStefano Zampini     } else if (A->hermitian) {
47400121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
475a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
47600121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
477a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
478a49dc2a2SStefano Zampini #endif
479a49dc2a2SStefano Zampini     } else { /* symmetric case */
48000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
481a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
48200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
483a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
484a49dc2a2SStefano Zampini     }
485*4905a7bcSToby Isaac     ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
486*4905a7bcSToby Isaac   } else if (A->factortype == MAT_FACTOR_QR) {
487*4905a7bcSToby Isaac     char trans;
48885e2c93fSHong Zhang 
489*4905a7bcSToby Isaac     if (PetscDefined(USE_COMPLEX)) {
490*4905a7bcSToby Isaac       trans = 'C';
491*4905a7bcSToby Isaac     } else {
492*4905a7bcSToby Isaac       trans = 'T';
493*4905a7bcSToby Isaac     }
494*4905a7bcSToby Isaac     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
495*4905a7bcSToby Isaac     PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", &trans, &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&xlda,mat->fwork,&mat->lfwork,&info));
496*4905a7bcSToby Isaac     ierr = PetscFPTrapPop();CHKERRQ(ierr);
497*4905a7bcSToby Isaac     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform");
498*4905a7bcSToby Isaac     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
499*4905a7bcSToby Isaac     PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "N", "N", &mat->rank,&nrhs,mat->v,&mat->lda,x,&xlda,&info));
500*4905a7bcSToby Isaac     ierr = PetscFPTrapPop();CHKERRQ(ierr);
501*4905a7bcSToby Isaac     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve");
502*4905a7bcSToby Isaac     for (PetscInt j = 0; j < nrhs; j++) {
503*4905a7bcSToby Isaac       for (PetscInt i = mat->rank; i < k; i++) {
504*4905a7bcSToby Isaac         x[j*xlda + i] = 0.;
505*4905a7bcSToby Isaac       }
506*4905a7bcSToby Isaac     }
507*4905a7bcSToby Isaac     ierr = PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank)));CHKERRQ(ierr);
508*4905a7bcSToby Isaac   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
509*4905a7bcSToby Isaac   PetscFunctionReturn(0);
510*4905a7bcSToby Isaac }
511*4905a7bcSToby Isaac 
512*4905a7bcSToby Isaac static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy)
513*4905a7bcSToby Isaac {
514*4905a7bcSToby Isaac   PetscErrorCode    ierr;
515*4905a7bcSToby Isaac   const PetscScalar *x;
516*4905a7bcSToby Isaac   PetscScalar       *y;
517*4905a7bcSToby Isaac   PetscBLASInt      m=0,k=0;
518*4905a7bcSToby Isaac 
519*4905a7bcSToby Isaac   PetscFunctionBegin;
520*4905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
521*4905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
522*4905a7bcSToby Isaac   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
523*4905a7bcSToby Isaac   if (k < m) {
524*4905a7bcSToby Isaac     ierr = PetscMalloc1(m, &y);CHKERRQ(ierr);
525*4905a7bcSToby Isaac     ierr = PetscArraycpy(y,x,m);CHKERRQ(ierr);
526*4905a7bcSToby Isaac   } else {
527*4905a7bcSToby Isaac     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
528*4905a7bcSToby Isaac     ierr = PetscArraycpy(y,x,m);CHKERRQ(ierr);
529*4905a7bcSToby Isaac   }
530*4905a7bcSToby Isaac   ierr = MatSolve_SeqDense_Internal(A, y, PetscMax(k,m), 1, k);CHKERRQ(ierr);
531*4905a7bcSToby Isaac   if (k < m) {
532*4905a7bcSToby Isaac     PetscScalar *yv;
533*4905a7bcSToby Isaac     ierr = VecGetArray(yy,&yv);CHKERRQ(ierr);
534*4905a7bcSToby Isaac     ierr = PetscArraycpy(yv, y, k);CHKERRQ(ierr);
535*4905a7bcSToby Isaac     ierr = VecRestoreArray(yy,&yv);CHKERRQ(ierr);
536*4905a7bcSToby Isaac     ierr = PetscFree(y);CHKERRQ(ierr);
537*4905a7bcSToby Isaac   } else {
538*4905a7bcSToby Isaac     ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
539*4905a7bcSToby Isaac     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
540*4905a7bcSToby Isaac   }
541*4905a7bcSToby Isaac   PetscFunctionReturn(0);
542*4905a7bcSToby Isaac }
543*4905a7bcSToby Isaac 
544*4905a7bcSToby Isaac static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X)
545*4905a7bcSToby Isaac {
546*4905a7bcSToby Isaac   PetscErrorCode    ierr;
547*4905a7bcSToby Isaac   const PetscScalar *b;
548*4905a7bcSToby Isaac   PetscScalar       *x;
549*4905a7bcSToby Isaac   PetscInt          n, _blda, _xlda;
550*4905a7bcSToby Isaac   PetscBLASInt      nrhs=0,m=0,k=0,blda=0,xlda=0;
551*4905a7bcSToby Isaac 
552*4905a7bcSToby Isaac   PetscFunctionBegin;
553*4905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
554*4905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
555*4905a7bcSToby Isaac   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
556*4905a7bcSToby Isaac   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
557*4905a7bcSToby Isaac   ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
558*4905a7bcSToby Isaac   ierr = MatDenseGetLDA(B,&_blda);CHKERRQ(ierr);
559*4905a7bcSToby Isaac   ierr = PetscBLASIntCast(_blda, &blda);CHKERRQ(ierr);
560*4905a7bcSToby Isaac   ierr = MatDenseGetLDA(X,&_xlda);CHKERRQ(ierr);
561*4905a7bcSToby Isaac   ierr = PetscBLASIntCast(_xlda, &xlda);CHKERRQ(ierr);
562*4905a7bcSToby Isaac   if (xlda < m) {
563*4905a7bcSToby Isaac     ierr = PetscMalloc1(nrhs * m, &x);CHKERRQ(ierr);
564*4905a7bcSToby Isaac     if (blda == m) {
565*4905a7bcSToby Isaac       ierr = PetscArraycpy(x,b,blda*nrhs);CHKERRQ(ierr);
566*4905a7bcSToby Isaac     } else {
567*4905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
568*4905a7bcSToby Isaac         ierr = PetscArraycpy(&x[j*m],&b[j*blda],m);CHKERRQ(ierr);
569*4905a7bcSToby Isaac       }
570*4905a7bcSToby Isaac     }
571*4905a7bcSToby Isaac   } else {
572*4905a7bcSToby Isaac     ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr);
573*4905a7bcSToby Isaac     if (blda == xlda) {
574*4905a7bcSToby Isaac       ierr = PetscArraycpy(x,b,blda*nrhs);CHKERRQ(ierr);
575*4905a7bcSToby Isaac     } else {
576*4905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
577*4905a7bcSToby Isaac         ierr = PetscArraycpy(&x[j*xlda],&b[j*blda],m);CHKERRQ(ierr);
578*4905a7bcSToby Isaac       }
579*4905a7bcSToby Isaac     }
580*4905a7bcSToby Isaac   }
581*4905a7bcSToby Isaac   ierr = MatSolve_SeqDense_Internal(A, x, PetscMax(m,xlda), nrhs, k);CHKERRQ(ierr);
582*4905a7bcSToby Isaac   if (xlda < m) {
583*4905a7bcSToby Isaac     PetscScalar *xv;
584*4905a7bcSToby Isaac     ierr = MatDenseGetArray(X,&xv);CHKERRQ(ierr);
585*4905a7bcSToby Isaac     for (PetscInt j = 0; j < nrhs; j++) {
586*4905a7bcSToby Isaac       ierr = PetscArraycpy(&xv[j*xlda],&x[j*m],k);CHKERRQ(ierr);
587*4905a7bcSToby Isaac     }
588*4905a7bcSToby Isaac     ierr = MatDenseRestoreArray(X,&xv);CHKERRQ(ierr);
589*4905a7bcSToby Isaac     ierr = PetscFree(x);CHKERRQ(ierr);
590*4905a7bcSToby Isaac   } else {
5911683a169SBarry Smith     ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
5928c778c55SBarry Smith     ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr);
593*4905a7bcSToby Isaac   }
59485e2c93fSHong Zhang   PetscFunctionReturn(0);
59585e2c93fSHong Zhang }
59685e2c93fSHong Zhang 
59700121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
59800121966SStefano Zampini 
599e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
600da3a660dSBarry Smith {
601c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
602dfbe8321SBarry Smith   PetscErrorCode    ierr;
603f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
604f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
605c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
60667e560aaSBarry Smith 
6073a40ed3dSBarry Smith   PetscFunctionBegin;
608c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
609f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
6101ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
611580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
6128208b9aeSStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
61300121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6148b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
61500121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
616e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve");
6178208b9aeSStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
618a49dc2a2SStefano Zampini     if (A->spd) {
61900121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
62000121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
62100121966SStefano Zampini #endif
62200121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6238b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
62400121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
62500121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
62600121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
62700121966SStefano Zampini #endif
628a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
629a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
630a49dc2a2SStefano Zampini     } else if (A->hermitian) {
63100121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
63200121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
63300121966SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
63400121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
63500121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
636ae7cfcebSSatish Balay #endif
637a49dc2a2SStefano Zampini     } else { /* symmetric case */
63800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
639a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
64000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
641a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
642da3a660dSBarry Smith     }
643*4905a7bcSToby Isaac   } else if (A->factortype == MAT_FACTOR_QR) {
644*4905a7bcSToby Isaac     if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
645*4905a7bcSToby Isaac       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
646*4905a7bcSToby Isaac       PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "T", "N", &m,&one,mat->v,&mat->lda,y,&m,&info));
647*4905a7bcSToby Isaac       ierr = PetscFPTrapPop();CHKERRQ(ierr);
648*4905a7bcSToby Isaac       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve");
649*4905a7bcSToby Isaac       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
650*4905a7bcSToby Isaac       PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", "N", &m,&one,&mat->rank,mat->v,&mat->lda,mat->tau,y,&m,mat->fwork,&mat->lfwork,&info));
651*4905a7bcSToby Isaac       ierr = PetscFPTrapPop();CHKERRQ(ierr);
652*4905a7bcSToby Isaac       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform");
653*4905a7bcSToby Isaac     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"QR factored matrix cannot be used for transpose solve");
654a49dc2a2SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
655f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
6561ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
657dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
6583a40ed3dSBarry Smith   PetscFunctionReturn(0);
659da3a660dSBarry Smith }
6606ee01492SSatish Balay 
661db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
662db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
663db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
664ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
665db4efbfdSBarry Smith {
666db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
667db4efbfdSBarry Smith   PetscErrorCode ierr;
668db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
669db4efbfdSBarry Smith 
670db4efbfdSBarry Smith   PetscFunctionBegin;
671c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
672c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
673db4efbfdSBarry Smith   if (!mat->pivots) {
6748208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
6753bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
676db4efbfdSBarry Smith   }
677db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
6788e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6798b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
6808e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
6818e57ea43SSatish Balay 
682e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
683e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
6848208b9aeSStefano Zampini 
685db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6868208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
687db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
688d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
689db4efbfdSBarry Smith 
690f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
691f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
692f6224b95SHong Zhang 
693dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
694db4efbfdSBarry Smith   PetscFunctionReturn(0);
695db4efbfdSBarry Smith }
696db4efbfdSBarry Smith 
697a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
698ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
699db4efbfdSBarry Smith {
700db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
701db4efbfdSBarry Smith   PetscErrorCode ierr;
702c5df96a5SBarry Smith   PetscBLASInt   info,n;
703db4efbfdSBarry Smith 
704db4efbfdSBarry Smith   PetscFunctionBegin;
705c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
706db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
707a49dc2a2SStefano Zampini   if (A->spd) {
70800121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
7098b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
71000121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
711a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
712a49dc2a2SStefano Zampini   } else if (A->hermitian) {
713a49dc2a2SStefano Zampini     if (!mat->pivots) {
714a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
715a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
716a49dc2a2SStefano Zampini     }
717a49dc2a2SStefano Zampini     if (!mat->fwork) {
718a49dc2a2SStefano Zampini       PetscScalar dummy;
719a49dc2a2SStefano Zampini 
720a49dc2a2SStefano Zampini       mat->lfwork = -1;
72100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
722a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
72300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
724a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
725a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
726a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
727a49dc2a2SStefano Zampini     }
72800121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
729a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
73000121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
731a49dc2a2SStefano Zampini #endif
732a49dc2a2SStefano Zampini   } else { /* symmetric case */
733a49dc2a2SStefano Zampini     if (!mat->pivots) {
734a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
735a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
736a49dc2a2SStefano Zampini     }
737a49dc2a2SStefano Zampini     if (!mat->fwork) {
738a49dc2a2SStefano Zampini       PetscScalar dummy;
739a49dc2a2SStefano Zampini 
740a49dc2a2SStefano Zampini       mat->lfwork = -1;
74100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
742a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
74300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
744a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
745a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
746a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
747a49dc2a2SStefano Zampini     }
74800121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
749a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
75000121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
751a49dc2a2SStefano Zampini   }
752e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
7538208b9aeSStefano Zampini 
754db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
7558208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
756db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
757d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
7582205254eSKarl Rupp 
759f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
760f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
761f6224b95SHong Zhang 
762eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
763db4efbfdSBarry Smith   PetscFunctionReturn(0);
764db4efbfdSBarry Smith }
765db4efbfdSBarry Smith 
7660481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
767db4efbfdSBarry Smith {
768db4efbfdSBarry Smith   PetscErrorCode ierr;
769db4efbfdSBarry Smith   MatFactorInfo  info;
770db4efbfdSBarry Smith 
771db4efbfdSBarry Smith   PetscFunctionBegin;
772db4efbfdSBarry Smith   info.fill = 1.0;
7732205254eSKarl Rupp 
774c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
775f4259b30SLisandro Dalcin   ierr = (*fact->ops->choleskyfactor)(fact,NULL,&info);CHKERRQ(ierr);
776db4efbfdSBarry Smith   PetscFunctionReturn(0);
777db4efbfdSBarry Smith }
778db4efbfdSBarry Smith 
779ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
780db4efbfdSBarry Smith {
781db4efbfdSBarry Smith   PetscFunctionBegin;
782c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
7831bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
784719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
785bd443b22SStefano Zampini   fact->ops->solve                 = MatSolve_SeqDense;
786bd443b22SStefano Zampini   fact->ops->matsolve              = MatMatSolve_SeqDense;
787bd443b22SStefano Zampini   fact->ops->solvetranspose        = MatSolveTranspose_SeqDense;
788db4efbfdSBarry Smith   PetscFunctionReturn(0);
789db4efbfdSBarry Smith }
790db4efbfdSBarry Smith 
791ca15aa20SStefano Zampini PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
792db4efbfdSBarry Smith {
793db4efbfdSBarry Smith   PetscFunctionBegin;
794b66fe19dSMatthew G Knepley   fact->preallocated           = PETSC_TRUE;
795c3ef05f6SHong Zhang   fact->assembled              = PETSC_TRUE;
796719d5645SBarry Smith   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
797bd443b22SStefano Zampini   fact->ops->solve             = MatSolve_SeqDense;
798bd443b22SStefano Zampini   fact->ops->matsolve          = MatMatSolve_SeqDense;
799bd443b22SStefano Zampini   fact->ops->solvetranspose    = MatSolveTranspose_SeqDense;
800db4efbfdSBarry Smith   PetscFunctionReturn(0);
801db4efbfdSBarry Smith }
802db4efbfdSBarry Smith 
803*4905a7bcSToby Isaac static PetscErrorCode MatQRFactor_SeqDense(Mat A,IS col,const MatFactorInfo *minfo)
804*4905a7bcSToby Isaac {
805*4905a7bcSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
806*4905a7bcSToby Isaac   PetscErrorCode ierr;
807*4905a7bcSToby Isaac   PetscBLASInt   n,m,info, min, max;
808*4905a7bcSToby Isaac 
809*4905a7bcSToby Isaac   PetscFunctionBegin;
810*4905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
811*4905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
812*4905a7bcSToby Isaac   if (!mat->tau) {
813*4905a7bcSToby Isaac     PetscInt mn = PetscMin(A->rmap->n, A->cmap->n);
814*4905a7bcSToby Isaac     ierr = PetscMalloc1(mn,&mat->tau);CHKERRQ(ierr);
815*4905a7bcSToby Isaac     ierr = PetscLogObjectMemory((PetscObject)A,mn*sizeof(PetscScalar));CHKERRQ(ierr);
816*4905a7bcSToby Isaac   }
817*4905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
818*4905a7bcSToby Isaac   if (!mat->fwork) {
819*4905a7bcSToby Isaac     PetscScalar dummy;
820*4905a7bcSToby Isaac 
821*4905a7bcSToby Isaac     mat->lfwork = -1;
822*4905a7bcSToby Isaac     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
823*4905a7bcSToby Isaac     PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,&dummy,&mat->lfwork,&info));
824*4905a7bcSToby Isaac     ierr = PetscFPTrapPop();CHKERRQ(ierr);
825*4905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
826*4905a7bcSToby Isaac     ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
827*4905a7bcSToby Isaac     ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
828*4905a7bcSToby Isaac   }
829*4905a7bcSToby Isaac   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
830*4905a7bcSToby Isaac   PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,mat->fwork,&mat->lfwork,&info));
831*4905a7bcSToby Isaac   ierr = PetscFPTrapPop();CHKERRQ(ierr);
832*4905a7bcSToby Isaac   if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to QR factorization");
833*4905a7bcSToby Isaac   max = PetscMax(m, n);
834*4905a7bcSToby Isaac   min = PetscMin(m, n);
835*4905a7bcSToby Isaac   // TODO: try to estimate rank or test for and use geqp3 for rank revealing QR.  For now just say rank is min of m and n
836*4905a7bcSToby Isaac   mat->rank = min;
837*4905a7bcSToby Isaac 
838*4905a7bcSToby Isaac   A->ops->solve             = MatSolve_SeqDense;
839*4905a7bcSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense;
840*4905a7bcSToby Isaac   A->factortype             = MAT_FACTOR_QR;
841*4905a7bcSToby Isaac   if (m == n) {
842*4905a7bcSToby Isaac     A->ops->solvetranspose  = MatSolveTranspose_SeqDense;
843*4905a7bcSToby Isaac   }
844*4905a7bcSToby Isaac 
845*4905a7bcSToby Isaac   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
846*4905a7bcSToby Isaac   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
847*4905a7bcSToby Isaac 
848*4905a7bcSToby Isaac   ierr = PetscLogFlops(2.0*min*min*(max-min/3.0));CHKERRQ(ierr);
849*4905a7bcSToby Isaac   PetscFunctionReturn(0);
850*4905a7bcSToby Isaac }
851*4905a7bcSToby Isaac 
852*4905a7bcSToby Isaac static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
853*4905a7bcSToby Isaac {
854*4905a7bcSToby Isaac   PetscErrorCode ierr;
855*4905a7bcSToby Isaac   MatFactorInfo  info;
856*4905a7bcSToby Isaac 
857*4905a7bcSToby Isaac   PetscFunctionBegin;
858*4905a7bcSToby Isaac   info.fill = 1.0;
859*4905a7bcSToby Isaac 
860*4905a7bcSToby Isaac   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
861*4905a7bcSToby Isaac   ierr = MatQRFactor_SeqDense(fact,NULL,&info);CHKERRQ(ierr);
862*4905a7bcSToby Isaac   PetscFunctionReturn(0);
863*4905a7bcSToby Isaac }
864*4905a7bcSToby Isaac 
865*4905a7bcSToby Isaac static PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
866*4905a7bcSToby Isaac {
867*4905a7bcSToby Isaac   PetscErrorCode ierr;
868*4905a7bcSToby Isaac 
869*4905a7bcSToby Isaac   PetscFunctionBegin;
870*4905a7bcSToby Isaac   fact->assembled                  = PETSC_TRUE;
871*4905a7bcSToby Isaac   fact->preallocated               = PETSC_TRUE;
872*4905a7bcSToby Isaac   fact->ops->solve                 = MatSolve_SeqDense;
873*4905a7bcSToby Isaac   fact->ops->matsolve              = MatMatSolve_SeqDense;
874*4905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)fact,"MatQRFactorNumeric_C",MatQRFactorNumeric_SeqDense);CHKERRQ(ierr);
875*4905a7bcSToby Isaac   PetscFunctionReturn(0);
876*4905a7bcSToby Isaac }
877*4905a7bcSToby Isaac 
878*4905a7bcSToby Isaac 
879ca15aa20SStefano Zampini /* uses LAPACK */
880cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
881db4efbfdSBarry Smith {
882db4efbfdSBarry Smith   PetscErrorCode ierr;
883db4efbfdSBarry Smith 
884db4efbfdSBarry Smith   PetscFunctionBegin;
885ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
886db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
887ca15aa20SStefano Zampini   ierr = MatSetType(*fact,MATDENSE);CHKERRQ(ierr);
8882a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
889db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
8902a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
891db4efbfdSBarry Smith   } else {
892db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
893db4efbfdSBarry Smith   }
894d5f3da31SBarry Smith   (*fact)->factortype = ftype;
89500c67f3bSHong Zhang 
89600c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
89700c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
898db4efbfdSBarry Smith   PetscFunctionReturn(0);
899db4efbfdSBarry Smith }
900db4efbfdSBarry Smith 
901289bc588SBarry Smith /* ------------------------------------------------------------------*/
902e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
903289bc588SBarry Smith {
904c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
905d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
906d9ca1df4SBarry Smith   const PetscScalar *b;
907dfbe8321SBarry Smith   PetscErrorCode    ierr;
908d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
90923fff9afSBarry Smith   PetscBLASInt      o = 1,bm = 0;
910289bc588SBarry Smith 
9113a40ed3dSBarry Smith   PetscFunctionBegin;
912ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
913c70f7ee4SJunchao Zhang   if (A->offloadmask == PETSC_OFFLOAD_GPU) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
914ca15aa20SStefano Zampini #endif
915422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
916c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
917289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
9183bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
9192dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
920289bc588SBarry Smith   }
9211ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
922d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
923b965ef7fSBarry Smith   its  = its*lits;
924e32f2f54SBarry 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);
925289bc588SBarry Smith   while (its--) {
926fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
927289bc588SBarry Smith       for (i=0; i<m; i++) {
9283bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
92955a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
930289bc588SBarry Smith       }
931289bc588SBarry Smith     }
932fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
933289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
9343bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
93555a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
936289bc588SBarry Smith       }
937289bc588SBarry Smith     }
938289bc588SBarry Smith   }
939d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
9401ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
9413a40ed3dSBarry Smith   PetscFunctionReturn(0);
942289bc588SBarry Smith }
943289bc588SBarry Smith 
944289bc588SBarry Smith /* -----------------------------------------------------------------*/
945ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
946289bc588SBarry Smith {
947c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
948d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
949d9ca1df4SBarry Smith   PetscScalar       *y;
950dfbe8321SBarry Smith   PetscErrorCode    ierr;
9510805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
952ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
9533a40ed3dSBarry Smith 
9543a40ed3dSBarry Smith   PetscFunctionBegin;
955c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
956c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
957d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
9582bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
9595ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
9605ac36cfcSBarry Smith     PetscBLASInt i;
9615ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
9625ac36cfcSBarry Smith   } else {
9638b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
9645ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
9655ac36cfcSBarry Smith   }
966d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
9672bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
9683a40ed3dSBarry Smith   PetscFunctionReturn(0);
969289bc588SBarry Smith }
970800995b7SMatthew Knepley 
971ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
972289bc588SBarry Smith {
973c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
974d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
975dfbe8321SBarry Smith   PetscErrorCode    ierr;
9760805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
977d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
9783a40ed3dSBarry Smith 
9793a40ed3dSBarry Smith   PetscFunctionBegin;
980c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
981c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
982d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
9832bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
9845ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
9855ac36cfcSBarry Smith     PetscBLASInt i;
9865ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
9875ac36cfcSBarry Smith   } else {
9888b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
9895ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
9905ac36cfcSBarry Smith   }
991d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
9922bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
9933a40ed3dSBarry Smith   PetscFunctionReturn(0);
994289bc588SBarry Smith }
9956ee01492SSatish Balay 
996ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
997289bc588SBarry Smith {
998c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
999d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1000d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
1001dfbe8321SBarry Smith   PetscErrorCode    ierr;
10020805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
10033a40ed3dSBarry Smith 
10043a40ed3dSBarry Smith   PetscFunctionBegin;
1005c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1006c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
100717b127eeSStefano Zampini   ierr = VecCopy(zz,yy);CHKERRQ(ierr);
1008d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
1009d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
10101ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
10118b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
1012d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
10131ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1014dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
10153a40ed3dSBarry Smith   PetscFunctionReturn(0);
1016289bc588SBarry Smith }
10176ee01492SSatish Balay 
1018ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1019289bc588SBarry Smith {
1020c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1021d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1022d9ca1df4SBarry Smith   PetscScalar       *y;
1023dfbe8321SBarry Smith   PetscErrorCode    ierr;
10240805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
102587828ca2SBarry Smith   PetscScalar       _DOne=1.0;
10263a40ed3dSBarry Smith 
10273a40ed3dSBarry Smith   PetscFunctionBegin;
1028c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1029c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
103017b127eeSStefano Zampini   ierr = VecCopy(zz,yy);CHKERRQ(ierr);
1031d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
1032d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
10331ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
10348b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
1035d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
10361ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1037dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
10383a40ed3dSBarry Smith   PetscFunctionReturn(0);
1039289bc588SBarry Smith }
1040289bc588SBarry Smith 
1041289bc588SBarry Smith /* -----------------------------------------------------------------*/
1042e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1043289bc588SBarry Smith {
1044c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
10456849ba73SBarry Smith   PetscErrorCode ierr;
104613f74950SBarry Smith   PetscInt       i;
104767e560aaSBarry Smith 
10483a40ed3dSBarry Smith   PetscFunctionBegin;
1049d0f46423SBarry Smith   *ncols = A->cmap->n;
1050289bc588SBarry Smith   if (cols) {
1051854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
1052d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
1053289bc588SBarry Smith   }
1054289bc588SBarry Smith   if (vals) {
1055ca15aa20SStefano Zampini     const PetscScalar *v;
1056ca15aa20SStefano Zampini 
1057ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1058854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
1059ca15aa20SStefano Zampini     v   += row;
1060d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
1061ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1062289bc588SBarry Smith   }
10633a40ed3dSBarry Smith   PetscFunctionReturn(0);
1064289bc588SBarry Smith }
10656ee01492SSatish Balay 
1066e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1067289bc588SBarry Smith {
1068dfbe8321SBarry Smith   PetscErrorCode ierr;
10696e111a19SKarl Rupp 
1070606d414cSSatish Balay   PetscFunctionBegin;
1071606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
1072606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
10733a40ed3dSBarry Smith   PetscFunctionReturn(0);
1074289bc588SBarry Smith }
1075289bc588SBarry Smith /* ----------------------------------------------------------------*/
1076e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
1077289bc588SBarry Smith {
1078c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
1079ca15aa20SStefano Zampini   PetscScalar      *av;
108013f74950SBarry Smith   PetscInt         i,j,idx=0;
1081ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1082c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1083ca15aa20SStefano Zampini #endif
1084ca15aa20SStefano Zampini   PetscErrorCode   ierr;
1085d6dfbf8fSBarry Smith 
10863a40ed3dSBarry Smith   PetscFunctionBegin;
1087ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&av);CHKERRQ(ierr);
1088289bc588SBarry Smith   if (!mat->roworiented) {
1089dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1090289bc588SBarry Smith       for (j=0; j<n; j++) {
1091cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
1092cf9c20a2SJed Brown         if (PetscUnlikelyDebug(indexn[j] >= A->cmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
1093289bc588SBarry Smith         for (i=0; i<m; i++) {
1094cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
1095cf9c20a2SJed Brown           if (PetscUnlikelyDebug(indexm[i] >= A->rmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
1096ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1097289bc588SBarry Smith         }
1098289bc588SBarry Smith       }
10993a40ed3dSBarry Smith     } else {
1100289bc588SBarry Smith       for (j=0; j<n; j++) {
1101cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
1102cf9c20a2SJed Brown         if (PetscUnlikelyDebug(indexn[j] >= A->cmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
1103289bc588SBarry Smith         for (i=0; i<m; i++) {
1104cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
1105cf9c20a2SJed Brown           if (PetscUnlikelyDebug(indexm[i] >= A->rmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
1106ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1107289bc588SBarry Smith         }
1108289bc588SBarry Smith       }
1109289bc588SBarry Smith     }
11103a40ed3dSBarry Smith   } else {
1111dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1112e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
1113cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
1114cf9c20a2SJed Brown         if (PetscUnlikelyDebug(indexm[i] >= A->rmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
1115e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
1116cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
1117cf9c20a2SJed Brown           if (PetscUnlikelyDebug(indexn[j] >= A->cmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
1118ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1119e8d4e0b9SBarry Smith         }
1120e8d4e0b9SBarry Smith       }
11213a40ed3dSBarry Smith     } else {
1122289bc588SBarry Smith       for (i=0; i<m; i++) {
1123cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
1124cf9c20a2SJed Brown         if (PetscUnlikelyDebug(indexm[i] >= A->rmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
1125289bc588SBarry Smith         for (j=0; j<n; j++) {
1126cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
1127cf9c20a2SJed Brown           if (PetscUnlikelyDebug(indexn[j] >= A->cmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
1128ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1129289bc588SBarry Smith         }
1130289bc588SBarry Smith       }
1131289bc588SBarry Smith     }
1132e8d4e0b9SBarry Smith   }
1133ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
1134ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1135c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
1136c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1137ca15aa20SStefano Zampini #endif
1138ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&av);CHKERRQ(ierr);
1139ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1140c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1141ca15aa20SStefano Zampini #endif
11423a40ed3dSBarry Smith   PetscFunctionReturn(0);
1143289bc588SBarry Smith }
1144e8d4e0b9SBarry Smith 
1145e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1146ae80bb75SLois Curfman McInnes {
1147ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1148ca15aa20SStefano Zampini   const PetscScalar *vv;
114913f74950SBarry Smith   PetscInt          i,j;
1150ca15aa20SStefano Zampini   PetscErrorCode    ierr;
1151ae80bb75SLois Curfman McInnes 
11523a40ed3dSBarry Smith   PetscFunctionBegin;
1153ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1154ae80bb75SLois Curfman McInnes   /* row-oriented output */
1155ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
115697e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1157e32f2f54SBarry 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);
1158ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
11596f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1160e32f2f54SBarry 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);
1161ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1162ae80bb75SLois Curfman McInnes     }
1163ae80bb75SLois Curfman McInnes   }
1164ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
11653a40ed3dSBarry Smith   PetscFunctionReturn(0);
1166ae80bb75SLois Curfman McInnes }
1167ae80bb75SLois Curfman McInnes 
1168289bc588SBarry Smith /* -----------------------------------------------------------------*/
1169289bc588SBarry Smith 
11708491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1171aabbc4fbSShri Abhyankar {
1172aabbc4fbSShri Abhyankar   PetscErrorCode    ierr;
11738491ab44SLisandro Dalcin   PetscBool         skipHeader;
11748491ab44SLisandro Dalcin   PetscViewerFormat format;
11758491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
11768491ab44SLisandro Dalcin   const PetscScalar *v;
11778491ab44SLisandro Dalcin   PetscScalar       *vwork;
1178aabbc4fbSShri Abhyankar 
1179aabbc4fbSShri Abhyankar   PetscFunctionBegin;
11808491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
11818491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
11828491ab44SLisandro Dalcin   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
11838491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1184aabbc4fbSShri Abhyankar 
11858491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
11868491ab44SLisandro Dalcin 
11878491ab44SLisandro Dalcin   /* write matrix header */
11888491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
11898491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
11908491ab44SLisandro Dalcin   if (!skipHeader) {ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);}
11918491ab44SLisandro Dalcin 
11928491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
11938491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
11948491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
11958491ab44SLisandro Dalcin     /* store row lengths for each row */
11968491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
11978491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
11988491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
11998491ab44SLisandro Dalcin     /* store column indices (zero start index) */
12008491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
12018491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
12028491ab44SLisandro Dalcin         iwork[k] = j;
12038491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
12048491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
12058491ab44SLisandro Dalcin   }
12068491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
12078491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
12088491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
12098491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
12108491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
12118491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
12128491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
12138491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
12148491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
12158491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
12168491ab44SLisandro Dalcin   PetscFunctionReturn(0);
12178491ab44SLisandro Dalcin }
12188491ab44SLisandro Dalcin 
12198491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
12208491ab44SLisandro Dalcin {
12218491ab44SLisandro Dalcin   PetscErrorCode ierr;
12228491ab44SLisandro Dalcin   PetscBool      skipHeader;
12238491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
12248491ab44SLisandro Dalcin   PetscInt       rows,cols;
12258491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
12268491ab44SLisandro Dalcin 
12278491ab44SLisandro Dalcin   PetscFunctionBegin;
12288491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
12298491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
12308491ab44SLisandro Dalcin 
12318491ab44SLisandro Dalcin   if (!skipHeader) {
12328491ab44SLisandro Dalcin     ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
12338491ab44SLisandro Dalcin     if (header[0] != MAT_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
12348491ab44SLisandro Dalcin     M = header[1]; N = header[2];
12358491ab44SLisandro Dalcin     if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M);
12368491ab44SLisandro Dalcin     if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N);
12378491ab44SLisandro Dalcin     nz = header[3];
12388491ab44SLisandro Dalcin     if (nz != MATRIX_BINARY_FORMAT_DENSE && nz < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %D in file",nz);
1239aabbc4fbSShri Abhyankar   } else {
12408491ab44SLisandro Dalcin     ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
12418491ab44SLisandro Dalcin     if (M < 0 || N < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Matrix binary file header was skipped, thus the user must specify the global sizes of input matrix");
12428491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1243e6324fbbSBarry Smith   }
1244aabbc4fbSShri Abhyankar 
12458491ab44SLisandro Dalcin   /* setup global sizes if not set */
12468491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
12478491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
12488491ab44SLisandro Dalcin   ierr = MatSetUp(mat);CHKERRQ(ierr);
12498491ab44SLisandro Dalcin   /* check if global sizes are correct */
12508491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
12518491ab44SLisandro Dalcin   if (M != rows || N != cols) SETERRQ4(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different sizes (%d, %d) than the input matrix (%d, %d)",M,N,rows,cols);
1252aabbc4fbSShri Abhyankar 
12538491ab44SLisandro Dalcin   ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
12548491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
12558491ab44SLisandro Dalcin   ierr = MatDenseGetArray(mat,&v);CHKERRQ(ierr);
12568491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
12578491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
12588491ab44SLisandro Dalcin     PetscInt nnz = m*N;
12598491ab44SLisandro Dalcin     /* read in matrix values */
12608491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&vwork);CHKERRQ(ierr);
12618491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
12628491ab44SLisandro Dalcin     /* store values in column major order */
12638491ab44SLisandro Dalcin     for (j=0; j<N; j++)
12648491ab44SLisandro Dalcin       for (i=0; i<m; i++)
12658491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
12668491ab44SLisandro Dalcin     ierr = PetscFree(vwork);CHKERRQ(ierr);
12678491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
12688491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
12698491ab44SLisandro Dalcin     /* read in row lengths */
12708491ab44SLisandro Dalcin     ierr = PetscMalloc1(m,&rlens);CHKERRQ(ierr);
12718491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
12728491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
12738491ab44SLisandro Dalcin     /* read in column indices and values */
12748491ab44SLisandro Dalcin     ierr = PetscMalloc2(nnz,&icols,nnz,&vwork);CHKERRQ(ierr);
12758491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
12768491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
12778491ab44SLisandro Dalcin     /* store values in column major order */
12788491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
12798491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
12808491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
12818491ab44SLisandro Dalcin     ierr = PetscFree(rlens);CHKERRQ(ierr);
12828491ab44SLisandro Dalcin     ierr = PetscFree2(icols,vwork);CHKERRQ(ierr);
1283aabbc4fbSShri Abhyankar   }
12848491ab44SLisandro Dalcin   ierr = MatDenseRestoreArray(mat,&v);CHKERRQ(ierr);
12858491ab44SLisandro Dalcin   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
12868491ab44SLisandro Dalcin   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1287aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1288aabbc4fbSShri Abhyankar }
1289aabbc4fbSShri Abhyankar 
1290eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1291eb91f321SVaclav Hapla {
1292eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1293eb91f321SVaclav Hapla   PetscErrorCode ierr;
1294eb91f321SVaclav Hapla 
1295eb91f321SVaclav Hapla   PetscFunctionBegin;
1296eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1297eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1298eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
1299eb91f321SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1300eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1301eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1302eb91f321SVaclav Hapla   if (isbinary) {
13038491ab44SLisandro Dalcin     ierr = MatLoad_Dense_Binary(newMat,viewer);CHKERRQ(ierr);
1304eb91f321SVaclav Hapla   } else if (ishdf5) {
1305eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
1306eb91f321SVaclav Hapla     ierr = MatLoad_Dense_HDF5(newMat,viewer);CHKERRQ(ierr);
1307eb91f321SVaclav Hapla #else
1308eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1309eb91f321SVaclav Hapla #endif
1310eb91f321SVaclav Hapla   } else {
1311eb91f321SVaclav 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);
1312eb91f321SVaclav Hapla   }
1313eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1314eb91f321SVaclav Hapla }
1315eb91f321SVaclav Hapla 
13166849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1317289bc588SBarry Smith {
1318932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1319dfbe8321SBarry Smith   PetscErrorCode    ierr;
132013f74950SBarry Smith   PetscInt          i,j;
13212dcb1b2aSMatthew Knepley   const char        *name;
1322ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1323f3ef73ceSBarry Smith   PetscViewerFormat format;
13245f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1325ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
13265f481a85SSatish Balay #endif
1327932b0c3eSLois Curfman McInnes 
13283a40ed3dSBarry Smith   PetscFunctionBegin;
1329ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1330b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1331456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
13323a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1333fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1334d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1335d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1336ca15aa20SStefano Zampini       v    = av + i;
133777431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1338d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1339aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1340329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
134157622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1342329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
134357622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
13446831982aSBarry Smith         }
134580cd9d93SLois Curfman McInnes #else
13466831982aSBarry Smith         if (*v) {
134757622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
13486831982aSBarry Smith         }
134980cd9d93SLois Curfman McInnes #endif
13501b807ce4Svictorle         v += a->lda;
135180cd9d93SLois Curfman McInnes       }
1352b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
135380cd9d93SLois Curfman McInnes     }
1354d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
13553a40ed3dSBarry Smith   } else {
1356d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1357aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
135847989497SBarry Smith     /* determine if matrix has all real values */
1359ca15aa20SStefano Zampini     v = av;
1360d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1361ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
136247989497SBarry Smith     }
136347989497SBarry Smith #endif
1364fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
13653a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1366d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1367d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1368fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1369ffac6cdbSBarry Smith     }
1370ffac6cdbSBarry Smith 
1371d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1372ca15aa20SStefano Zampini       v = av + i;
1373d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1374aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
137547989497SBarry Smith         if (allreal) {
1376c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
137747989497SBarry Smith         } else {
1378c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
137947989497SBarry Smith         }
1380289bc588SBarry Smith #else
1381c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1382289bc588SBarry Smith #endif
13831b807ce4Svictorle         v += a->lda;
1384289bc588SBarry Smith       }
1385b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1386289bc588SBarry Smith     }
1387fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1388b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1389ffac6cdbSBarry Smith     }
1390d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1391da3a660dSBarry Smith   }
1392ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1393b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
13943a40ed3dSBarry Smith   PetscFunctionReturn(0);
1395289bc588SBarry Smith }
1396289bc588SBarry Smith 
13979804daf3SBarry Smith #include <petscdraw.h>
1398e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1399f1af5d2fSBarry Smith {
1400f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
14016849ba73SBarry Smith   PetscErrorCode    ierr;
1402383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1403383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1404ca15aa20SStefano Zampini   const PetscScalar *v;
1405b0a32e0cSBarry Smith   PetscViewer       viewer;
1406b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1407f3ef73ceSBarry Smith   PetscViewerFormat format;
1408f1af5d2fSBarry Smith 
1409f1af5d2fSBarry Smith   PetscFunctionBegin;
1410f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1411b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1412b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1413f1af5d2fSBarry Smith 
1414f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1415ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1416fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1417383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1418f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1419f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1420383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1421f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1422f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1423f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1424ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1425ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1426ca15aa20SStefano Zampini         else continue;
1427b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1428f1af5d2fSBarry Smith       }
1429f1af5d2fSBarry Smith     }
1430383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1431f1af5d2fSBarry Smith   } else {
1432f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1433f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1434b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1435b05fc000SLisandro Dalcin     PetscDraw popup;
1436b05fc000SLisandro Dalcin 
1437f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1438f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1439f1af5d2fSBarry Smith     }
1440383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1441b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
144245f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1443383922c3SLisandro Dalcin 
1444383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1445f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1446f1af5d2fSBarry Smith       x_l = j;
1447f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1448f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1449f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1450f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1451b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1452b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1453f1af5d2fSBarry Smith       }
1454f1af5d2fSBarry Smith     }
1455383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1456f1af5d2fSBarry Smith   }
1457ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1458f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1459f1af5d2fSBarry Smith }
1460f1af5d2fSBarry Smith 
1461e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1462f1af5d2fSBarry Smith {
1463b0a32e0cSBarry Smith   PetscDraw      draw;
1464ace3abfcSBarry Smith   PetscBool      isnull;
1465329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1466dfbe8321SBarry Smith   PetscErrorCode ierr;
1467f1af5d2fSBarry Smith 
1468f1af5d2fSBarry Smith   PetscFunctionBegin;
1469b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1470b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1471abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1472f1af5d2fSBarry Smith 
1473d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1474f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1475b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1476832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1477b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
14780298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1479832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1480f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1481f1af5d2fSBarry Smith }
1482f1af5d2fSBarry Smith 
1483dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1484932b0c3eSLois Curfman McInnes {
1485dfbe8321SBarry Smith   PetscErrorCode ierr;
1486ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1487932b0c3eSLois Curfman McInnes 
14883a40ed3dSBarry Smith   PetscFunctionBegin;
1489251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1490251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1491251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
14920f5bd95cSBarry Smith 
1493c45a1595SBarry Smith   if (iascii) {
1494c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
14950f5bd95cSBarry Smith   } else if (isbinary) {
1496637a0070SStefano Zampini     ierr = MatView_Dense_Binary(A,viewer);CHKERRQ(ierr);
1497f1af5d2fSBarry Smith   } else if (isdraw) {
1498f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1499932b0c3eSLois Curfman McInnes   }
15003a40ed3dSBarry Smith   PetscFunctionReturn(0);
1501932b0c3eSLois Curfman McInnes }
1502289bc588SBarry Smith 
1503637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array)
1504d3042a70SBarry Smith {
1505d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1506d3042a70SBarry Smith 
1507d3042a70SBarry Smith   PetscFunctionBegin;
15085ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
15095ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
15105ea7661aSPierre Jolivet   if (a->unplacedarray) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreArray() first");
1511d3042a70SBarry Smith   a->unplacedarray       = a->v;
1512d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1513d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1514637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1515ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1516c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1517ca15aa20SStefano Zampini #endif
1518d3042a70SBarry Smith   PetscFunctionReturn(0);
1519d3042a70SBarry Smith }
1520d3042a70SBarry Smith 
1521d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1522d3042a70SBarry Smith {
1523d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1524d3042a70SBarry Smith 
1525d3042a70SBarry Smith   PetscFunctionBegin;
15265ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
15275ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1528d3042a70SBarry Smith   a->v             = a->unplacedarray;
1529d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1530d3042a70SBarry Smith   a->unplacedarray = NULL;
1531ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1532c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1533ca15aa20SStefano Zampini #endif
1534d3042a70SBarry Smith   PetscFunctionReturn(0);
1535d3042a70SBarry Smith }
1536d3042a70SBarry Smith 
1537d5ea218eSStefano Zampini static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A,const PetscScalar *array)
1538d5ea218eSStefano Zampini {
1539d5ea218eSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1540d5ea218eSStefano Zampini   PetscErrorCode ierr;
1541d5ea218eSStefano Zampini 
1542d5ea218eSStefano Zampini   PetscFunctionBegin;
15435ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
15445ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1545d5ea218eSStefano Zampini   if (!a->user_alloc) { ierr = PetscFree(a->v);CHKERRQ(ierr); }
1546d5ea218eSStefano Zampini   a->v           = (PetscScalar*) array;
1547d5ea218eSStefano Zampini   a->user_alloc  = PETSC_FALSE;
1548d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1549d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1550d5ea218eSStefano Zampini #endif
1551d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1552d5ea218eSStefano Zampini }
1553d5ea218eSStefano Zampini 
1554ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1555289bc588SBarry Smith {
1556ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1557dfbe8321SBarry Smith   PetscErrorCode ierr;
155890f02eecSBarry Smith 
15593a40ed3dSBarry Smith   PetscFunctionBegin;
1560aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1561d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1562a5a9c739SBarry Smith #endif
1563*4905a7bcSToby Isaac   ierr = PetscFree(l->tau);CHKERRQ(ierr);
156405b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1565a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1566abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
15676857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1568637a0070SStefano Zampini   if (!l->unplaced_user_alloc) {ierr = PetscFree(l->unplacedarray);CHKERRQ(ierr);}
15695ea7661aSPierre Jolivet   if (l->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
15705ea7661aSPierre Jolivet   if (l->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
15716947451fSStefano Zampini   ierr = VecDestroy(&l->cvec);CHKERRQ(ierr);
15725ea7661aSPierre Jolivet   ierr = MatDestroy(&l->cmat);CHKERRQ(ierr);
1573bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1574dbd8c25aSHong Zhang 
1575f4259b30SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)mat,NULL);CHKERRQ(ierr);
1576*4905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatQRFactor_C",NULL);CHKERRQ(ierr);
1577*4905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatQRFactorNumeric_C",NULL);CHKERRQ(ierr);
1578*4905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatQRFactorSymbolic_C",NULL);CHKERRQ(ierr);
157949a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1580ad16ce7aSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseSetLDA_C",NULL);CHKERRQ(ierr);
1581bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
158252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
1583d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1584d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
1585d5ea218eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseReplaceArray_C",NULL);CHKERRQ(ierr);
158652c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL);CHKERRQ(ierr);
158752c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL);CHKERRQ(ierr);
15886947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayWrite_C",NULL);CHKERRQ(ierr);
15896947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayWrite_C",NULL);CHKERRQ(ierr);
15908baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
15918baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
15928baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
15938baccfbdSHong Zhang #endif
1594d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
1595d24d4204SJose E. Roman   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_scalapack_C",NULL);CHKERRQ(ierr);
1596d24d4204SJose E. Roman #endif
15972bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
15982bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL);CHKERRQ(ierr);
15994222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL);CHKERRQ(ierr);
16004222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL);CHKERRQ(ierr);
16012bf066beSStefano Zampini #endif
1602bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
16034222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
16044222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL);CHKERRQ(ierr);
16054222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
16064222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
160752c5f739Sprj- 
160886aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
160986aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
16106947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVec_C",NULL);CHKERRQ(ierr);
16116947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVec_C",NULL);CHKERRQ(ierr);
16126947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecRead_C",NULL);CHKERRQ(ierr);
16136947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecRead_C",NULL);CHKERRQ(ierr);
16146947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecWrite_C",NULL);CHKERRQ(ierr);
16156947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecWrite_C",NULL);CHKERRQ(ierr);
16165ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetSubMatrix_C",NULL);CHKERRQ(ierr);
16175ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreSubMatrix_C",NULL);CHKERRQ(ierr);
16183a40ed3dSBarry Smith   PetscFunctionReturn(0);
1619289bc588SBarry Smith }
1620289bc588SBarry Smith 
1621e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1622289bc588SBarry Smith {
1623c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
16246849ba73SBarry Smith   PetscErrorCode ierr;
16256536e3caSStefano Zampini   PetscInt       k,j,m = A->rmap->n, M = mat->lda, n = A->cmap->n;
162687828ca2SBarry Smith   PetscScalar    *v,tmp;
162748b35521SBarry Smith 
16283a40ed3dSBarry Smith   PetscFunctionBegin;
16296536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
16306536e3caSStefano Zampini     if (m == n) { /* in place transpose */
1631ca15aa20SStefano Zampini       ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1632d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1633289bc588SBarry Smith         for (k=0; k<j; k++) {
16341b807ce4Svictorle           tmp        = v[j + k*M];
16351b807ce4Svictorle           v[j + k*M] = v[k + j*M];
16361b807ce4Svictorle           v[k + j*M] = tmp;
1637289bc588SBarry Smith         }
1638289bc588SBarry Smith       }
1639ca15aa20SStefano Zampini       ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
16406536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
16416536e3caSStefano Zampini       PetscScalar *v2;
16426536e3caSStefano Zampini       PetscLayout tmplayout;
16436536e3caSStefano Zampini 
16446536e3caSStefano Zampini       ierr = PetscMalloc1((size_t)m*n,&v2);CHKERRQ(ierr);
16456536e3caSStefano Zampini       ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
16466536e3caSStefano Zampini       for (j=0; j<n; j++) {
16476536e3caSStefano Zampini         for (k=0; k<m; k++) v2[j + (size_t)k*n] = v[k + (size_t)j*M];
16486536e3caSStefano Zampini       }
16496536e3caSStefano Zampini       ierr = PetscArraycpy(v,v2,(size_t)m*n);CHKERRQ(ierr);
16506536e3caSStefano Zampini       ierr = PetscFree(v2);CHKERRQ(ierr);
16516536e3caSStefano Zampini       ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
16526536e3caSStefano Zampini       /* cleanup size dependent quantities */
16536536e3caSStefano Zampini       ierr = VecDestroy(&mat->cvec);CHKERRQ(ierr);
16546536e3caSStefano Zampini       ierr = MatDestroy(&mat->cmat);CHKERRQ(ierr);
16556536e3caSStefano Zampini       ierr = PetscFree(mat->pivots);CHKERRQ(ierr);
16566536e3caSStefano Zampini       ierr = PetscFree(mat->fwork);CHKERRQ(ierr);
16576536e3caSStefano Zampini       ierr = MatDestroy(&mat->ptapwork);CHKERRQ(ierr);
16586536e3caSStefano Zampini       /* swap row/col layouts */
16596536e3caSStefano Zampini       mat->lda  = n;
16606536e3caSStefano Zampini       tmplayout = A->rmap;
16616536e3caSStefano Zampini       A->rmap   = A->cmap;
16626536e3caSStefano Zampini       A->cmap   = tmplayout;
16636536e3caSStefano Zampini     }
16643a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1665d3e5ee88SLois Curfman McInnes     Mat          tmat;
1666ec8511deSBarry Smith     Mat_SeqDense *tmatd;
166787828ca2SBarry Smith     PetscScalar  *v2;
1668af36a384SStefano Zampini     PetscInt     M2;
1669ea709b57SSatish Balay 
16706536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
1671ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1672d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
16737adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
16740298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1675ca15aa20SStefano Zampini     } else tmat = *matout;
1676ca15aa20SStefano Zampini 
1677ca15aa20SStefano Zampini     ierr  = MatDenseGetArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
1678ca15aa20SStefano Zampini     ierr  = MatDenseGetArray(tmat,&v2);CHKERRQ(ierr);
1679ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1680ca15aa20SStefano Zampini     M2    = tmatd->lda;
1681d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1682af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1683d3e5ee88SLois Curfman McInnes     }
1684ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(tmat,&v2);CHKERRQ(ierr);
1685ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
16866d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16876d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
16886536e3caSStefano Zampini     *matout = tmat;
168948b35521SBarry Smith   }
16903a40ed3dSBarry Smith   PetscFunctionReturn(0);
1691289bc588SBarry Smith }
1692289bc588SBarry Smith 
1693e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1694289bc588SBarry Smith {
1695c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1696c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1697ca15aa20SStefano Zampini   PetscInt          i;
1698ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
1699ca15aa20SStefano Zampini   PetscErrorCode    ierr;
17009ea5d5aeSSatish Balay 
17013a40ed3dSBarry Smith   PetscFunctionBegin;
1702d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1703d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1704ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A1,&v1);CHKERRQ(ierr);
1705ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A2,&v2);CHKERRQ(ierr);
1706ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
1707ca15aa20SStefano Zampini     ierr = PetscArraycmp(v1,v2,A1->rmap->n,flg);CHKERRQ(ierr);
1708ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1709ca15aa20SStefano Zampini     v1 += mat1->lda;
1710ca15aa20SStefano Zampini     v2 += mat2->lda;
17111b807ce4Svictorle   }
1712ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A1,&v1);CHKERRQ(ierr);
1713ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A2,&v2);CHKERRQ(ierr);
171477c4ece6SBarry Smith   *flg = PETSC_TRUE;
17153a40ed3dSBarry Smith   PetscFunctionReturn(0);
1716289bc588SBarry Smith }
1717289bc588SBarry Smith 
1718e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1719289bc588SBarry Smith {
1720c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
172113f74950SBarry Smith   PetscInt          i,n,len;
1722ca15aa20SStefano Zampini   PetscScalar       *x;
1723ca15aa20SStefano Zampini   const PetscScalar *vv;
1724ca15aa20SStefano Zampini   PetscErrorCode    ierr;
172544cd7ae7SLois Curfman McInnes 
17263a40ed3dSBarry Smith   PetscFunctionBegin;
17277a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
17281ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1729d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1730ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1731e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
173244cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1733ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1734289bc588SBarry Smith   }
1735ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
17361ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
17373a40ed3dSBarry Smith   PetscFunctionReturn(0);
1738289bc588SBarry Smith }
1739289bc588SBarry Smith 
1740e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1741289bc588SBarry Smith {
1742c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1743f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1744ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1745dfbe8321SBarry Smith   PetscErrorCode    ierr;
1746d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
174755659b69SBarry Smith 
17483a40ed3dSBarry Smith   PetscFunctionBegin;
1749ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&vv);CHKERRQ(ierr);
175028988994SBarry Smith   if (ll) {
17517a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1752f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1753e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1754da3a660dSBarry Smith     for (i=0; i<m; i++) {
1755da3a660dSBarry Smith       x = l[i];
1756ca15aa20SStefano Zampini       v = vv + i;
1757b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1758da3a660dSBarry Smith     }
1759f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1760eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1761da3a660dSBarry Smith   }
176228988994SBarry Smith   if (rr) {
17637a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1764f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1765e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1766da3a660dSBarry Smith     for (i=0; i<n; i++) {
1767da3a660dSBarry Smith       x = r[i];
1768ca15aa20SStefano Zampini       v = vv + i*mat->lda;
17692205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1770da3a660dSBarry Smith     }
1771f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1772eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1773da3a660dSBarry Smith   }
1774ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&vv);CHKERRQ(ierr);
17753a40ed3dSBarry Smith   PetscFunctionReturn(0);
1776289bc588SBarry Smith }
1777289bc588SBarry Smith 
1778ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1779289bc588SBarry Smith {
1780c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1781ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1782329f5518SBarry Smith   PetscReal         sum  = 0.0;
1783d0f46423SBarry Smith   PetscInt          lda  =mat->lda,m=A->rmap->n,i,j;
1784efee365bSSatish Balay   PetscErrorCode    ierr;
178555659b69SBarry Smith 
17863a40ed3dSBarry Smith   PetscFunctionBegin;
1787ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
1788ca15aa20SStefano Zampini   v    = vv;
1789289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1790a5ce6ee0Svictorle     if (lda>m) {
1791d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1792ca15aa20SStefano Zampini         v = vv+j*lda;
1793a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1794a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1795a5ce6ee0Svictorle         }
1796a5ce6ee0Svictorle       }
1797a5ce6ee0Svictorle     } else {
1798570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1799570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
180073cf7048SBarry Smith       PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&cnt,v,&one));
1801570b7f6dSBarry Smith     }
1802570b7f6dSBarry Smith #else
1803d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1804329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1805289bc588SBarry Smith       }
1806a5ce6ee0Svictorle     }
18078f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1808570b7f6dSBarry Smith #endif
1809dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
18103a40ed3dSBarry Smith   } else if (type == NORM_1) {
1811064f8208SBarry Smith     *nrm = 0.0;
1812d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1813ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
1814289bc588SBarry Smith       sum = 0.0;
1815d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
181633a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1817289bc588SBarry Smith       }
1818064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1819289bc588SBarry Smith     }
1820eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
18213a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1822064f8208SBarry Smith     *nrm = 0.0;
1823d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1824ca15aa20SStefano Zampini       v   = vv + j;
1825289bc588SBarry Smith       sum = 0.0;
1826d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
18271b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1828289bc588SBarry Smith       }
1829064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1830289bc588SBarry Smith     }
1831eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1832e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
1833ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
18343a40ed3dSBarry Smith   PetscFunctionReturn(0);
1835289bc588SBarry Smith }
1836289bc588SBarry Smith 
1837e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1838289bc588SBarry Smith {
1839c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
184063ba0a88SBarry Smith   PetscErrorCode ierr;
184167e560aaSBarry Smith 
18423a40ed3dSBarry Smith   PetscFunctionBegin;
1843b5a2b587SKris Buschelman   switch (op) {
1844b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
18454e0d8c25SBarry Smith     aij->roworiented = flg;
1846b5a2b587SKris Buschelman     break;
1847512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1848b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
18493971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
18508c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
185113fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1852b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1853b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
18540f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
18555021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
1856071fcb05SBarry Smith   case MAT_SORTED_FULL:
18575021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
18585021d80fSJed Brown     break;
18595021d80fSJed Brown   case MAT_SPD:
186077e54ba9SKris Buschelman   case MAT_SYMMETRIC:
186177e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
18629a4540c5SBarry Smith   case MAT_HERMITIAN:
18639a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
18645021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
186577e54ba9SKris Buschelman     break;
1866b5a2b587SKris Buschelman   default:
1867e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
18683a40ed3dSBarry Smith   }
18693a40ed3dSBarry Smith   PetscFunctionReturn(0);
1870289bc588SBarry Smith }
1871289bc588SBarry Smith 
1872e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
18736f0a148fSBarry Smith {
1874ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
18756849ba73SBarry Smith   PetscErrorCode ierr;
1876d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
1877ca15aa20SStefano Zampini   PetscScalar    *v;
18783a40ed3dSBarry Smith 
18793a40ed3dSBarry Smith   PetscFunctionBegin;
1880ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1881a5ce6ee0Svictorle   if (lda>m) {
1882d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1883ca15aa20SStefano Zampini       ierr = PetscArrayzero(v+j*lda,m);CHKERRQ(ierr);
1884a5ce6ee0Svictorle     }
1885a5ce6ee0Svictorle   } else {
1886ca15aa20SStefano Zampini     ierr = PetscArrayzero(v,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
1887a5ce6ee0Svictorle   }
1888ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
18893a40ed3dSBarry Smith   PetscFunctionReturn(0);
18906f0a148fSBarry Smith }
18916f0a148fSBarry Smith 
1892e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
18936f0a148fSBarry Smith {
189497b48c8fSBarry Smith   PetscErrorCode    ierr;
1895ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1896b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
1897ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
189897b48c8fSBarry Smith   const PetscScalar *xx;
189955659b69SBarry Smith 
19003a40ed3dSBarry Smith   PetscFunctionBegin;
190176bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1902b9679d65SBarry Smith     for (i=0; i<N; i++) {
1903b9679d65SBarry Smith       if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1904b9679d65SBarry 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);
1905b9679d65SBarry Smith     }
190676bd3646SJed Brown   }
1907ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1908b9679d65SBarry Smith 
190997b48c8fSBarry Smith   /* fix right hand side if needed */
191097b48c8fSBarry Smith   if (x && b) {
191197b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
191297b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
19132205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
191497b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
191597b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
191697b48c8fSBarry Smith   }
191797b48c8fSBarry Smith 
1918ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
19196f0a148fSBarry Smith   for (i=0; i<N; i++) {
1920ca15aa20SStefano Zampini     slot = v + rows[i];
1921b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
19226f0a148fSBarry Smith   }
1923f4df32b1SMatthew Knepley   if (diag != 0.0) {
1924b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
19256f0a148fSBarry Smith     for (i=0; i<N; i++) {
1926ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1927f4df32b1SMatthew Knepley       *slot = diag;
19286f0a148fSBarry Smith     }
19296f0a148fSBarry Smith   }
1930ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
19313a40ed3dSBarry Smith   PetscFunctionReturn(0);
19326f0a148fSBarry Smith }
1933557bce09SLois Curfman McInnes 
193449a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
193549a6ff4bSBarry Smith {
193649a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
193749a6ff4bSBarry Smith 
193849a6ff4bSBarry Smith   PetscFunctionBegin;
193949a6ff4bSBarry Smith   *lda = mat->lda;
194049a6ff4bSBarry Smith   PetscFunctionReturn(0);
194149a6ff4bSBarry Smith }
194249a6ff4bSBarry Smith 
1943637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array)
194464e87e97SBarry Smith {
1945c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
19463a40ed3dSBarry Smith 
19473a40ed3dSBarry Smith   PetscFunctionBegin;
1948616b8fbbSStefano Zampini   if (mat->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
194964e87e97SBarry Smith   *array = mat->v;
19503a40ed3dSBarry Smith   PetscFunctionReturn(0);
195164e87e97SBarry Smith }
19520754003eSLois Curfman McInnes 
1953637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array)
1954ff14e315SSatish Balay {
19553a40ed3dSBarry Smith   PetscFunctionBegin;
1956637a0070SStefano Zampini   *array = NULL;
19573a40ed3dSBarry Smith   PetscFunctionReturn(0);
1958ff14e315SSatish Balay }
19590754003eSLois Curfman McInnes 
1960dec5eb66SMatthew G Knepley /*@C
196149a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
196249a6ff4bSBarry Smith 
1963ad16ce7aSStefano Zampini    Not collective
196449a6ff4bSBarry Smith 
196549a6ff4bSBarry Smith    Input Parameter:
196649a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
196749a6ff4bSBarry Smith 
196849a6ff4bSBarry Smith    Output Parameter:
196949a6ff4bSBarry Smith .   lda - the leading dimension
197049a6ff4bSBarry Smith 
197149a6ff4bSBarry Smith    Level: intermediate
197249a6ff4bSBarry Smith 
1973ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseSetLDA()
197449a6ff4bSBarry Smith @*/
197549a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
197649a6ff4bSBarry Smith {
197749a6ff4bSBarry Smith   PetscErrorCode ierr;
197849a6ff4bSBarry Smith 
197949a6ff4bSBarry Smith   PetscFunctionBegin;
1980d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1981d5ea218eSStefano Zampini   PetscValidPointer(lda,2);
198249a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
198349a6ff4bSBarry Smith   PetscFunctionReturn(0);
198449a6ff4bSBarry Smith }
198549a6ff4bSBarry Smith 
198649a6ff4bSBarry Smith /*@C
1987ad16ce7aSStefano Zampini    MatDenseSetLDA - Sets the leading dimension of the array used by the dense matrix
1988ad16ce7aSStefano Zampini 
1989ad16ce7aSStefano Zampini    Not collective
1990ad16ce7aSStefano Zampini 
1991ad16ce7aSStefano Zampini    Input Parameter:
1992ad16ce7aSStefano Zampini +  mat - a MATSEQDENSE or MATMPIDENSE matrix
1993ad16ce7aSStefano Zampini -  lda - the leading dimension
1994ad16ce7aSStefano Zampini 
1995ad16ce7aSStefano Zampini    Level: intermediate
1996ad16ce7aSStefano Zampini 
1997ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetLDA()
1998ad16ce7aSStefano Zampini @*/
1999ad16ce7aSStefano Zampini PetscErrorCode  MatDenseSetLDA(Mat A,PetscInt lda)
2000ad16ce7aSStefano Zampini {
2001ad16ce7aSStefano Zampini   PetscErrorCode ierr;
2002ad16ce7aSStefano Zampini 
2003ad16ce7aSStefano Zampini   PetscFunctionBegin;
2004ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2005ad16ce7aSStefano Zampini   ierr = PetscTryMethod(A,"MatDenseSetLDA_C",(Mat,PetscInt),(A,lda));CHKERRQ(ierr);
2006ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2007ad16ce7aSStefano Zampini }
2008ad16ce7aSStefano Zampini 
2009ad16ce7aSStefano Zampini /*@C
20106947451fSStefano Zampini    MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored
201173a71a0fSBarry Smith 
20128572280aSBarry Smith    Logically Collective on Mat
201373a71a0fSBarry Smith 
201473a71a0fSBarry Smith    Input Parameter:
20156947451fSStefano Zampini .  mat - a dense matrix
201673a71a0fSBarry Smith 
201773a71a0fSBarry Smith    Output Parameter:
201873a71a0fSBarry Smith .   array - pointer to the data
201973a71a0fSBarry Smith 
202073a71a0fSBarry Smith    Level: intermediate
202173a71a0fSBarry Smith 
20226947451fSStefano Zampini .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
202373a71a0fSBarry Smith @*/
20248c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
202573a71a0fSBarry Smith {
202673a71a0fSBarry Smith   PetscErrorCode ierr;
202773a71a0fSBarry Smith 
202873a71a0fSBarry Smith   PetscFunctionBegin;
2029d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2030d5ea218eSStefano Zampini   PetscValidPointer(array,2);
20318c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
203273a71a0fSBarry Smith   PetscFunctionReturn(0);
203373a71a0fSBarry Smith }
203473a71a0fSBarry Smith 
2035dec5eb66SMatthew G Knepley /*@C
2036579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
203773a71a0fSBarry Smith 
20388572280aSBarry Smith    Logically Collective on Mat
20398572280aSBarry Smith 
20408572280aSBarry Smith    Input Parameters:
20416947451fSStefano Zampini +  mat - a dense matrix
2042a2b725a8SWilliam Gropp -  array - pointer to the data
20438572280aSBarry Smith 
20448572280aSBarry Smith    Level: intermediate
20458572280aSBarry Smith 
20466947451fSStefano Zampini .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
20478572280aSBarry Smith @*/
20488572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
20498572280aSBarry Smith {
20508572280aSBarry Smith   PetscErrorCode ierr;
20518572280aSBarry Smith 
20528572280aSBarry Smith   PetscFunctionBegin;
2053d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2054d5ea218eSStefano Zampini   PetscValidPointer(array,2);
20558572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
20568572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
2057637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
2058637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2059637a0070SStefano Zampini #endif
20608572280aSBarry Smith   PetscFunctionReturn(0);
20618572280aSBarry Smith }
20628572280aSBarry Smith 
20638572280aSBarry Smith /*@C
20646947451fSStefano Zampini    MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored
20658572280aSBarry Smith 
20668572280aSBarry Smith    Not Collective
20678572280aSBarry Smith 
20688572280aSBarry Smith    Input Parameter:
20696947451fSStefano Zampini .  mat - a dense matrix
20708572280aSBarry Smith 
20718572280aSBarry Smith    Output Parameter:
20728572280aSBarry Smith .   array - pointer to the data
20738572280aSBarry Smith 
20748572280aSBarry Smith    Level: intermediate
20758572280aSBarry Smith 
20766947451fSStefano Zampini .seealso: MatDenseRestoreArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
20778572280aSBarry Smith @*/
20788572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
20798572280aSBarry Smith {
20808572280aSBarry Smith   PetscErrorCode ierr;
20818572280aSBarry Smith 
20828572280aSBarry Smith   PetscFunctionBegin;
2083d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2084d5ea218eSStefano Zampini   PetscValidPointer(array,2);
20858572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
20868572280aSBarry Smith   PetscFunctionReturn(0);
20878572280aSBarry Smith }
20888572280aSBarry Smith 
20898572280aSBarry Smith /*@C
20906947451fSStefano Zampini    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead()
20918572280aSBarry Smith 
209273a71a0fSBarry Smith    Not Collective
209373a71a0fSBarry Smith 
209473a71a0fSBarry Smith    Input Parameters:
20956947451fSStefano Zampini +  mat - a dense matrix
2096a2b725a8SWilliam Gropp -  array - pointer to the data
209773a71a0fSBarry Smith 
209873a71a0fSBarry Smith    Level: intermediate
209973a71a0fSBarry Smith 
21006947451fSStefano Zampini .seealso: MatDenseGetArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
210173a71a0fSBarry Smith @*/
21028572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
210373a71a0fSBarry Smith {
210473a71a0fSBarry Smith   PetscErrorCode ierr;
210573a71a0fSBarry Smith 
210673a71a0fSBarry Smith   PetscFunctionBegin;
2107d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2108d5ea218eSStefano Zampini   PetscValidPointer(array,2);
21098572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
211073a71a0fSBarry Smith   PetscFunctionReturn(0);
211173a71a0fSBarry Smith }
211273a71a0fSBarry Smith 
21136947451fSStefano Zampini /*@C
21146947451fSStefano Zampini    MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored
21156947451fSStefano Zampini 
21166947451fSStefano Zampini    Not Collective
21176947451fSStefano Zampini 
21186947451fSStefano Zampini    Input Parameter:
21196947451fSStefano Zampini .  mat - a dense matrix
21206947451fSStefano Zampini 
21216947451fSStefano Zampini    Output Parameter:
21226947451fSStefano Zampini .   array - pointer to the data
21236947451fSStefano Zampini 
21246947451fSStefano Zampini    Level: intermediate
21256947451fSStefano Zampini 
21266947451fSStefano Zampini .seealso: MatDenseRestoreArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
21276947451fSStefano Zampini @*/
21286947451fSStefano Zampini PetscErrorCode  MatDenseGetArrayWrite(Mat A,PetscScalar **array)
21296947451fSStefano Zampini {
21306947451fSStefano Zampini   PetscErrorCode ierr;
21316947451fSStefano Zampini 
21326947451fSStefano Zampini   PetscFunctionBegin;
2133d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2134d5ea218eSStefano Zampini   PetscValidPointer(array,2);
21356947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
21366947451fSStefano Zampini   PetscFunctionReturn(0);
21376947451fSStefano Zampini }
21386947451fSStefano Zampini 
21396947451fSStefano Zampini /*@C
21406947451fSStefano Zampini    MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite()
21416947451fSStefano Zampini 
21426947451fSStefano Zampini    Not Collective
21436947451fSStefano Zampini 
21446947451fSStefano Zampini    Input Parameters:
21456947451fSStefano Zampini +  mat - a dense matrix
21466947451fSStefano Zampini -  array - pointer to the data
21476947451fSStefano Zampini 
21486947451fSStefano Zampini    Level: intermediate
21496947451fSStefano Zampini 
21506947451fSStefano Zampini .seealso: MatDenseGetArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
21516947451fSStefano Zampini @*/
21526947451fSStefano Zampini PetscErrorCode  MatDenseRestoreArrayWrite(Mat A,PetscScalar **array)
21536947451fSStefano Zampini {
21546947451fSStefano Zampini   PetscErrorCode ierr;
21556947451fSStefano Zampini 
21566947451fSStefano Zampini   PetscFunctionBegin;
2157d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2158d5ea218eSStefano Zampini   PetscValidPointer(array,2);
21596947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
21606947451fSStefano Zampini   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
21616947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
21626947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
21636947451fSStefano Zampini #endif
21646947451fSStefano Zampini   PetscFunctionReturn(0);
21656947451fSStefano Zampini }
21666947451fSStefano Zampini 
2167023c16fcSToby Isaac static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,MatReuse scall,Mat *B)
21680754003eSLois Curfman McInnes {
2169c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
21706849ba73SBarry Smith   PetscErrorCode ierr;
2171ca15aa20SStefano Zampini   PetscInt       i,j,nrows,ncols,blda;
21725d0c19d7SBarry Smith   const PetscInt *irow,*icol;
217387828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
21740754003eSLois Curfman McInnes   Mat            newmat;
21750754003eSLois Curfman McInnes 
21763a40ed3dSBarry Smith   PetscFunctionBegin;
217778b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
217878b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
2179e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2180e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
21810754003eSLois Curfman McInnes 
2182182d2002SSatish Balay   /* Check submatrixcall */
2183182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
218413f74950SBarry Smith     PetscInt n_cols,n_rows;
2185182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
218621a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2187f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
2188c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
218921a2c019SBarry Smith     }
2190182d2002SSatish Balay     newmat = *B;
2191182d2002SSatish Balay   } else {
21920754003eSLois Curfman McInnes     /* Create and fill new matrix */
2193ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
2194f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
21957adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
21960298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
2197182d2002SSatish Balay   }
2198182d2002SSatish Balay 
2199182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
2200ca15aa20SStefano Zampini   ierr = MatDenseGetArray(newmat,&bv);CHKERRQ(ierr);
2201ca15aa20SStefano Zampini   ierr = MatDenseGetLDA(newmat,&blda);CHKERRQ(ierr);
2202182d2002SSatish Balay   for (i=0; i<ncols; i++) {
22036de62eeeSBarry Smith     av = v + mat->lda*icol[i];
2204ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
2205ca15aa20SStefano Zampini     bv += blda;
22060754003eSLois Curfman McInnes   }
2207ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(newmat,&bv);CHKERRQ(ierr);
2208182d2002SSatish Balay 
2209182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
22106d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22116d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22120754003eSLois Curfman McInnes 
22130754003eSLois Curfman McInnes   /* Free work space */
221478b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
221578b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2216182d2002SSatish Balay   *B   = newmat;
22173a40ed3dSBarry Smith   PetscFunctionReturn(0);
22180754003eSLois Curfman McInnes }
22190754003eSLois Curfman McInnes 
22207dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2221905e6a2fSBarry Smith {
22226849ba73SBarry Smith   PetscErrorCode ierr;
222313f74950SBarry Smith   PetscInt       i;
2224905e6a2fSBarry Smith 
22253a40ed3dSBarry Smith   PetscFunctionBegin;
2226905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2227df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
2228905e6a2fSBarry Smith   }
2229905e6a2fSBarry Smith 
2230905e6a2fSBarry Smith   for (i=0; i<n; i++) {
2231023c16fcSToby Isaac     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],scall,&(*B)[i]);CHKERRQ(ierr);
2232905e6a2fSBarry Smith   }
22333a40ed3dSBarry Smith   PetscFunctionReturn(0);
2234905e6a2fSBarry Smith }
2235905e6a2fSBarry Smith 
2236e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2237c0aa2d19SHong Zhang {
2238c0aa2d19SHong Zhang   PetscFunctionBegin;
2239c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2240c0aa2d19SHong Zhang }
2241c0aa2d19SHong Zhang 
2242e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2243c0aa2d19SHong Zhang {
2244c0aa2d19SHong Zhang   PetscFunctionBegin;
2245c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2246c0aa2d19SHong Zhang }
2247c0aa2d19SHong Zhang 
2248a76f77c3SStefano Zampini PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
22494b0e389bSBarry Smith {
22504b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
22516849ba73SBarry Smith   PetscErrorCode    ierr;
2252ca15aa20SStefano Zampini   const PetscScalar *va;
2253ca15aa20SStefano Zampini   PetscScalar       *vb;
2254d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
22553a40ed3dSBarry Smith 
22563a40ed3dSBarry Smith   PetscFunctionBegin;
225733f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
225833f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
2259cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
22603a40ed3dSBarry Smith     PetscFunctionReturn(0);
22613a40ed3dSBarry Smith   }
2262e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
2263ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&va);CHKERRQ(ierr);
2264ca15aa20SStefano Zampini   ierr = MatDenseGetArray(B,&vb);CHKERRQ(ierr);
2265a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
22660dbb7854Svictorle     for (j=0; j<n; j++) {
2267ca15aa20SStefano Zampini       ierr = PetscArraycpy(vb+j*lda2,va+j*lda1,m);CHKERRQ(ierr);
2268a5ce6ee0Svictorle     }
2269a5ce6ee0Svictorle   } else {
2270ca15aa20SStefano Zampini     ierr = PetscArraycpy(vb,va,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2271a5ce6ee0Svictorle   }
2272ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(B,&vb);CHKERRQ(ierr);
2273ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&va);CHKERRQ(ierr);
2274ca15aa20SStefano Zampini   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2275ca15aa20SStefano Zampini   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2276273d9f13SBarry Smith   PetscFunctionReturn(0);
2277273d9f13SBarry Smith }
2278273d9f13SBarry Smith 
2279e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
2280273d9f13SBarry Smith {
2281dfbe8321SBarry Smith   PetscErrorCode ierr;
2282273d9f13SBarry Smith 
2283273d9f13SBarry Smith   PetscFunctionBegin;
228418992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
228518992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
228618992e5dSStefano Zampini   if (!A->preallocated) {
2287f4259b30SLisandro Dalcin     ierr = MatSeqDenseSetPreallocation(A,NULL);CHKERRQ(ierr);
228818992e5dSStefano Zampini   }
22893a40ed3dSBarry Smith   PetscFunctionReturn(0);
22904b0e389bSBarry Smith }
22914b0e389bSBarry Smith 
2292ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2293ba337c44SJed Brown {
2294ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2295ca15aa20SStefano Zampini   PetscScalar    *aa;
2296ca15aa20SStefano Zampini   PetscErrorCode ierr;
2297ba337c44SJed Brown 
2298ba337c44SJed Brown   PetscFunctionBegin;
2299ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2300ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2301ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2302ba337c44SJed Brown   PetscFunctionReturn(0);
2303ba337c44SJed Brown }
2304ba337c44SJed Brown 
2305ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2306ba337c44SJed Brown {
2307ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2308ca15aa20SStefano Zampini   PetscScalar    *aa;
2309ca15aa20SStefano Zampini   PetscErrorCode ierr;
2310ba337c44SJed Brown 
2311ba337c44SJed Brown   PetscFunctionBegin;
2312ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2313ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2314ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2315ba337c44SJed Brown   PetscFunctionReturn(0);
2316ba337c44SJed Brown }
2317ba337c44SJed Brown 
2318ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2319ba337c44SJed Brown {
2320ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2321ca15aa20SStefano Zampini   PetscScalar    *aa;
2322ca15aa20SStefano Zampini   PetscErrorCode ierr;
2323ba337c44SJed Brown 
2324ba337c44SJed Brown   PetscFunctionBegin;
2325ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2326ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
2327ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2328ba337c44SJed Brown   PetscFunctionReturn(0);
2329ba337c44SJed Brown }
2330284134d9SBarry Smith 
2331a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
23324222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2333a9fe9ddaSSatish Balay {
2334ee16a9a1SHong Zhang   PetscErrorCode ierr;
2335d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
23367a3c3d58SStefano Zampini   PetscBool      cisdense;
2337a9fe9ddaSSatish Balay 
2338ee16a9a1SHong Zhang   PetscFunctionBegin;
23394222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
23407a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
23417a3c3d58SStefano Zampini   if (!cisdense) {
23427a3c3d58SStefano Zampini     PetscBool flg;
23437a3c3d58SStefano Zampini 
2344ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
23454222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
23467a3c3d58SStefano Zampini   }
234718992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2348ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2349ee16a9a1SHong Zhang }
2350a9fe9ddaSSatish Balay 
2351a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2352a9fe9ddaSSatish Balay {
23536718818eSStefano Zampini   Mat_SeqDense       *a=(Mat_SeqDense*)A->data,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
23540805154bSBarry Smith   PetscBLASInt       m,n,k;
2355ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2356ca15aa20SStefano Zampini   PetscScalar       *cv;
2357a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2358c2916339SPierre Jolivet   PetscErrorCode    ierr;
2359a9fe9ddaSSatish Balay 
2360a9fe9ddaSSatish Balay   PetscFunctionBegin;
23618208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
23628208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2363c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
236449d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
2365ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
2366ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
23676718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
2368ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
2369ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2370ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
2371ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
23726718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2373a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2374a9fe9ddaSSatish Balay }
2375a9fe9ddaSSatish Balay 
23764222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
237769f65d41SStefano Zampini {
237869f65d41SStefano Zampini   PetscErrorCode ierr;
237969f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
23807a3c3d58SStefano Zampini   PetscBool      cisdense;
238169f65d41SStefano Zampini 
238269f65d41SStefano Zampini   PetscFunctionBegin;
23834222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
23847a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
23857a3c3d58SStefano Zampini   if (!cisdense) {
23867a3c3d58SStefano Zampini     PetscBool flg;
23877a3c3d58SStefano Zampini 
2388ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
23894222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
23907a3c3d58SStefano Zampini   }
239118992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
239269f65d41SStefano Zampini   PetscFunctionReturn(0);
239369f65d41SStefano Zampini }
239469f65d41SStefano Zampini 
239569f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
239669f65d41SStefano Zampini {
239769f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
239869f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
239969f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
24006718818eSStefano Zampini   const PetscScalar *av,*bv;
24016718818eSStefano Zampini   PetscScalar       *cv;
240269f65d41SStefano Zampini   PetscBLASInt      m,n,k;
240369f65d41SStefano Zampini   PetscScalar       _DOne=1.0,_DZero=0.0;
240469f65d41SStefano Zampini   PetscErrorCode    ierr;
240569f65d41SStefano Zampini 
240669f65d41SStefano Zampini   PetscFunctionBegin;
240749d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
240849d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
240969f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
241049d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
24116718818eSStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
24126718818eSStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
24136718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
24146718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
24156718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
24166718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
24176718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2418ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
241969f65d41SStefano Zampini   PetscFunctionReturn(0);
242069f65d41SStefano Zampini }
242169f65d41SStefano Zampini 
24224222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2423a9fe9ddaSSatish Balay {
2424ee16a9a1SHong Zhang   PetscErrorCode ierr;
2425d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
24267a3c3d58SStefano Zampini   PetscBool      cisdense;
2427a9fe9ddaSSatish Balay 
2428ee16a9a1SHong Zhang   PetscFunctionBegin;
24294222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
24307a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
24317a3c3d58SStefano Zampini   if (!cisdense) {
24327a3c3d58SStefano Zampini     PetscBool flg;
24337a3c3d58SStefano Zampini 
2434ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
24354222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
24367a3c3d58SStefano Zampini   }
243718992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2438ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2439ee16a9a1SHong Zhang }
2440a9fe9ddaSSatish Balay 
244175648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2442a9fe9ddaSSatish Balay {
2443a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2444a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
2445a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
24466718818eSStefano Zampini   const PetscScalar *av,*bv;
24476718818eSStefano Zampini   PetscScalar       *cv;
24480805154bSBarry Smith   PetscBLASInt      m,n,k;
2449a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2450c5df96a5SBarry Smith   PetscErrorCode    ierr;
2451a9fe9ddaSSatish Balay 
2452a9fe9ddaSSatish Balay   PetscFunctionBegin;
24538208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
24548208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2455c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
245649d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
24576718818eSStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
24586718818eSStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
24596718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
24606718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
24616718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
24626718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
24636718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2464ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2465a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2466a9fe9ddaSSatish Balay }
2467985db425SBarry Smith 
24684222ddf1SHong Zhang /* ----------------------------------------------- */
24694222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
24704222ddf1SHong Zhang {
24714222ddf1SHong Zhang   PetscFunctionBegin;
24724222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
24734222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
24744222ddf1SHong Zhang   PetscFunctionReturn(0);
24754222ddf1SHong Zhang }
24764222ddf1SHong Zhang 
24774222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
24784222ddf1SHong Zhang {
24794222ddf1SHong Zhang   PetscFunctionBegin;
24804222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
24814222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
24824222ddf1SHong Zhang   PetscFunctionReturn(0);
24834222ddf1SHong Zhang }
24844222ddf1SHong Zhang 
24854222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
24864222ddf1SHong Zhang {
24874222ddf1SHong Zhang   PetscFunctionBegin;
24884222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
24894222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
24904222ddf1SHong Zhang   PetscFunctionReturn(0);
24914222ddf1SHong Zhang }
24924222ddf1SHong Zhang 
24934222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
24944222ddf1SHong Zhang {
24954222ddf1SHong Zhang   PetscErrorCode ierr;
24964222ddf1SHong Zhang   Mat_Product    *product = C->product;
24974222ddf1SHong Zhang 
24984222ddf1SHong Zhang   PetscFunctionBegin;
24994222ddf1SHong Zhang   switch (product->type) {
25004222ddf1SHong Zhang   case MATPRODUCT_AB:
25014222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AB(C);CHKERRQ(ierr);
25024222ddf1SHong Zhang     break;
25034222ddf1SHong Zhang   case MATPRODUCT_AtB:
25044222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AtB(C);CHKERRQ(ierr);
25054222ddf1SHong Zhang     break;
25064222ddf1SHong Zhang   case MATPRODUCT_ABt:
25074222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_ABt(C);CHKERRQ(ierr);
25084222ddf1SHong Zhang     break;
25096718818eSStefano Zampini   default:
25104222ddf1SHong Zhang     break;
25114222ddf1SHong Zhang   }
25124222ddf1SHong Zhang   PetscFunctionReturn(0);
25134222ddf1SHong Zhang }
25144222ddf1SHong Zhang /* ----------------------------------------------- */
25154222ddf1SHong Zhang 
2516e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2517985db425SBarry Smith {
2518985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2519985db425SBarry Smith   PetscErrorCode     ierr;
2520d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2521985db425SBarry Smith   PetscScalar        *x;
2522ca15aa20SStefano Zampini   const PetscScalar *aa;
2523985db425SBarry Smith 
2524985db425SBarry Smith   PetscFunctionBegin;
2525e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2526985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2527985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2528ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2529e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2530985db425SBarry Smith   for (i=0; i<m; i++) {
2531985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2532985db425SBarry Smith     for (j=1; j<n; j++) {
2533ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2534985db425SBarry Smith     }
2535985db425SBarry Smith   }
2536ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2537985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2538985db425SBarry Smith   PetscFunctionReturn(0);
2539985db425SBarry Smith }
2540985db425SBarry Smith 
2541e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2542985db425SBarry Smith {
2543985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2544985db425SBarry Smith   PetscErrorCode    ierr;
2545d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2546985db425SBarry Smith   PetscScalar       *x;
2547985db425SBarry Smith   PetscReal         atmp;
2548ca15aa20SStefano Zampini   const PetscScalar *aa;
2549985db425SBarry Smith 
2550985db425SBarry Smith   PetscFunctionBegin;
2551e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2552985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2553985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2554ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2555e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2556985db425SBarry Smith   for (i=0; i<m; i++) {
25579189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2558985db425SBarry Smith     for (j=1; j<n; j++) {
2559ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2560985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2561985db425SBarry Smith     }
2562985db425SBarry Smith   }
2563ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2564985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2565985db425SBarry Smith   PetscFunctionReturn(0);
2566985db425SBarry Smith }
2567985db425SBarry Smith 
2568e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2569985db425SBarry Smith {
2570985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2571985db425SBarry Smith   PetscErrorCode    ierr;
2572d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2573985db425SBarry Smith   PetscScalar       *x;
2574ca15aa20SStefano Zampini   const PetscScalar *aa;
2575985db425SBarry Smith 
2576985db425SBarry Smith   PetscFunctionBegin;
2577e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2578ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2579985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2580985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2581e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2582985db425SBarry Smith   for (i=0; i<m; i++) {
2583985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2584985db425SBarry Smith     for (j=1; j<n; j++) {
2585ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2586985db425SBarry Smith     }
2587985db425SBarry Smith   }
2588985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2589ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2590985db425SBarry Smith   PetscFunctionReturn(0);
2591985db425SBarry Smith }
2592985db425SBarry Smith 
2593637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
25948d0534beSBarry Smith {
25958d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
25968d0534beSBarry Smith   PetscErrorCode    ierr;
25978d0534beSBarry Smith   PetscScalar       *x;
2598ca15aa20SStefano Zampini   const PetscScalar *aa;
25998d0534beSBarry Smith 
26008d0534beSBarry Smith   PetscFunctionBegin;
2601e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2602ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
26038d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2604ca15aa20SStefano Zampini   ierr = PetscArraycpy(x,aa+col*a->lda,A->rmap->n);CHKERRQ(ierr);
26058d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2606ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
26078d0534beSBarry Smith   PetscFunctionReturn(0);
26088d0534beSBarry Smith }
26098d0534beSBarry Smith 
261052c5f739Sprj- PETSC_INTERN PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
26110716a85fSBarry Smith {
26120716a85fSBarry Smith   PetscErrorCode    ierr;
26130716a85fSBarry Smith   PetscInt          i,j,m,n;
26141683a169SBarry Smith   const PetscScalar *a;
26150716a85fSBarry Smith 
26160716a85fSBarry Smith   PetscFunctionBegin;
26170716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2618580bdb30SBarry Smith   ierr = PetscArrayzero(norms,n);CHKERRQ(ierr);
26191683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&a);CHKERRQ(ierr);
26200716a85fSBarry Smith   if (type == NORM_2) {
26210716a85fSBarry Smith     for (i=0; i<n; i++) {
26220716a85fSBarry Smith       for (j=0; j<m; j++) {
26230716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
26240716a85fSBarry Smith       }
26250716a85fSBarry Smith       a += m;
26260716a85fSBarry Smith     }
26270716a85fSBarry Smith   } else if (type == NORM_1) {
26280716a85fSBarry Smith     for (i=0; i<n; i++) {
26290716a85fSBarry Smith       for (j=0; j<m; j++) {
26300716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
26310716a85fSBarry Smith       }
26320716a85fSBarry Smith       a += m;
26330716a85fSBarry Smith     }
26340716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
26350716a85fSBarry Smith     for (i=0; i<n; i++) {
26360716a85fSBarry Smith       for (j=0; j<m; j++) {
26370716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
26380716a85fSBarry Smith       }
26390716a85fSBarry Smith       a += m;
26400716a85fSBarry Smith     }
2641ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
26421683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&a);CHKERRQ(ierr);
26430716a85fSBarry Smith   if (type == NORM_2) {
26448f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
26450716a85fSBarry Smith   }
26460716a85fSBarry Smith   PetscFunctionReturn(0);
26470716a85fSBarry Smith }
26480716a85fSBarry Smith 
264973a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
265073a71a0fSBarry Smith {
265173a71a0fSBarry Smith   PetscErrorCode ierr;
265273a71a0fSBarry Smith   PetscScalar    *a;
2653637a0070SStefano Zampini   PetscInt       lda,m,n,i,j;
265473a71a0fSBarry Smith 
265573a71a0fSBarry Smith   PetscFunctionBegin;
265673a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
2657637a0070SStefano Zampini   ierr = MatDenseGetLDA(x,&lda);CHKERRQ(ierr);
26588c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
2659637a0070SStefano Zampini   for (j=0; j<n; j++) {
2660637a0070SStefano Zampini     for (i=0; i<m; i++) {
2661637a0070SStefano Zampini       ierr = PetscRandomGetValue(rctx,a+j*lda+i);CHKERRQ(ierr);
2662637a0070SStefano Zampini     }
266373a71a0fSBarry Smith   }
26648c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
266573a71a0fSBarry Smith   PetscFunctionReturn(0);
266673a71a0fSBarry Smith }
266773a71a0fSBarry Smith 
26683b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
26693b49f96aSBarry Smith {
26703b49f96aSBarry Smith   PetscFunctionBegin;
26713b49f96aSBarry Smith   *missing = PETSC_FALSE;
26723b49f96aSBarry Smith   PetscFunctionReturn(0);
26733b49f96aSBarry Smith }
267473a71a0fSBarry Smith 
2675ca15aa20SStefano Zampini /* vals is not const */
2676af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
267786aefd0dSHong Zhang {
2678ca15aa20SStefano Zampini   PetscErrorCode ierr;
267986aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2680ca15aa20SStefano Zampini   PetscScalar    *v;
268186aefd0dSHong Zhang 
268286aefd0dSHong Zhang   PetscFunctionBegin;
268386aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2684ca15aa20SStefano Zampini   ierr  = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2685ca15aa20SStefano Zampini   *vals = v+col*a->lda;
2686ca15aa20SStefano Zampini   ierr  = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
268786aefd0dSHong Zhang   PetscFunctionReturn(0);
268886aefd0dSHong Zhang }
268986aefd0dSHong Zhang 
2690af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
269186aefd0dSHong Zhang {
269286aefd0dSHong Zhang   PetscFunctionBegin;
2693f4259b30SLisandro Dalcin   *vals = NULL; /* user cannot accidently use the array later */
269486aefd0dSHong Zhang   PetscFunctionReturn(0);
269586aefd0dSHong Zhang }
2696abc3b08eSStefano Zampini 
2697289bc588SBarry Smith /* -------------------------------------------------------------------*/
2698a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2699905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2700905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2701905e6a2fSBarry Smith                                         MatMult_SeqDense,
270297304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
27037c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
27047c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2705f4259b30SLisandro Dalcin                                         NULL,
2706f4259b30SLisandro Dalcin                                         NULL,
2707f4259b30SLisandro Dalcin                                         NULL,
2708f4259b30SLisandro Dalcin                                 /* 10*/ NULL,
2709905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2710905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
271141f059aeSBarry Smith                                         MatSOR_SeqDense,
2712ec8511deSBarry Smith                                         MatTranspose_SeqDense,
271397304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2714905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2715905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2716905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2717905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2718c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2719c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2720905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2721905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2722d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2723f4259b30SLisandro Dalcin                                         NULL,
2724f4259b30SLisandro Dalcin                                         NULL,
2725f4259b30SLisandro Dalcin                                         NULL,
2726f4259b30SLisandro Dalcin                                         NULL,
27274994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2728f4259b30SLisandro Dalcin                                         NULL,
2729f4259b30SLisandro Dalcin                                         NULL,
2730f4259b30SLisandro Dalcin                                         NULL,
2731f4259b30SLisandro Dalcin                                         NULL,
2732d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2733f4259b30SLisandro Dalcin                                         NULL,
2734f4259b30SLisandro Dalcin                                         NULL,
2735f4259b30SLisandro Dalcin                                         NULL,
2736f4259b30SLisandro Dalcin                                         NULL,
2737d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
27387dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2739f4259b30SLisandro Dalcin                                         NULL,
27404b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2741a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2742d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2743a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
27447d68702bSBarry Smith                                         MatShift_Basic,
2745f4259b30SLisandro Dalcin                                         NULL,
27463f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
274773a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2748f4259b30SLisandro Dalcin                                         NULL,
2749f4259b30SLisandro Dalcin                                         NULL,
2750f4259b30SLisandro Dalcin                                         NULL,
2751f4259b30SLisandro Dalcin                                         NULL,
2752f4259b30SLisandro Dalcin                                 /* 54*/ NULL,
2753f4259b30SLisandro Dalcin                                         NULL,
2754f4259b30SLisandro Dalcin                                         NULL,
2755f4259b30SLisandro Dalcin                                         NULL,
2756f4259b30SLisandro Dalcin                                         NULL,
2757023c16fcSToby Isaac                                 /* 59*/ MatCreateSubMatrix_SeqDense,
2758e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2759e03a110bSBarry Smith                                         MatView_SeqDense,
2760f4259b30SLisandro Dalcin                                         NULL,
2761f4259b30SLisandro Dalcin                                         NULL,
2762f4259b30SLisandro Dalcin                                 /* 64*/ NULL,
2763f4259b30SLisandro Dalcin                                         NULL,
2764f4259b30SLisandro Dalcin                                         NULL,
2765f4259b30SLisandro Dalcin                                         NULL,
2766f4259b30SLisandro Dalcin                                         NULL,
2767d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
2768f4259b30SLisandro Dalcin                                         NULL,
2769f4259b30SLisandro Dalcin                                         NULL,
2770f4259b30SLisandro Dalcin                                         NULL,
2771f4259b30SLisandro Dalcin                                         NULL,
2772f4259b30SLisandro Dalcin                                 /* 74*/ NULL,
2773f4259b30SLisandro Dalcin                                         NULL,
2774f4259b30SLisandro Dalcin                                         NULL,
2775f4259b30SLisandro Dalcin                                         NULL,
2776f4259b30SLisandro Dalcin                                         NULL,
2777f4259b30SLisandro Dalcin                                 /* 79*/ NULL,
2778f4259b30SLisandro Dalcin                                         NULL,
2779f4259b30SLisandro Dalcin                                         NULL,
2780f4259b30SLisandro Dalcin                                         NULL,
27815bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2782637a0070SStefano Zampini                                         MatIsSymmetric_SeqDense,
27831cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2784f4259b30SLisandro Dalcin                                         NULL,
2785f4259b30SLisandro Dalcin                                         NULL,
2786f4259b30SLisandro Dalcin                                         NULL,
2787f4259b30SLisandro Dalcin                                 /* 89*/ NULL,
2788f4259b30SLisandro Dalcin                                         NULL,
2789a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2790f4259b30SLisandro Dalcin                                         NULL,
2791f4259b30SLisandro Dalcin                                         NULL,
2792f4259b30SLisandro Dalcin                                 /* 94*/ NULL,
2793f4259b30SLisandro Dalcin                                         NULL,
2794f4259b30SLisandro Dalcin                                         NULL,
279569f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2796f4259b30SLisandro Dalcin                                         NULL,
27974222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
2798f4259b30SLisandro Dalcin                                         NULL,
2799f4259b30SLisandro Dalcin                                         NULL,
2800ba337c44SJed Brown                                         MatConjugate_SeqDense,
2801f4259b30SLisandro Dalcin                                         NULL,
2802f4259b30SLisandro Dalcin                                 /*104*/ NULL,
2803ba337c44SJed Brown                                         MatRealPart_SeqDense,
2804ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2805f4259b30SLisandro Dalcin                                         NULL,
2806f4259b30SLisandro Dalcin                                         NULL,
2807f4259b30SLisandro Dalcin                                 /*109*/ NULL,
2808f4259b30SLisandro Dalcin                                         NULL,
28098d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2810aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
28113b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2812f4259b30SLisandro Dalcin                                 /*114*/ NULL,
2813f4259b30SLisandro Dalcin                                         NULL,
2814f4259b30SLisandro Dalcin                                         NULL,
2815f4259b30SLisandro Dalcin                                         NULL,
2816f4259b30SLisandro Dalcin                                         NULL,
2817f4259b30SLisandro Dalcin                                 /*119*/ NULL,
2818f4259b30SLisandro Dalcin                                         NULL,
2819f4259b30SLisandro Dalcin                                         NULL,
2820f4259b30SLisandro Dalcin                                         NULL,
2821f4259b30SLisandro Dalcin                                         NULL,
2822f4259b30SLisandro Dalcin                                 /*124*/ NULL,
28235df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
2824f4259b30SLisandro Dalcin                                         NULL,
2825f4259b30SLisandro Dalcin                                         NULL,
2826f4259b30SLisandro Dalcin                                         NULL,
2827f4259b30SLisandro Dalcin                                 /*129*/ NULL,
2828f4259b30SLisandro Dalcin                                         NULL,
2829f4259b30SLisandro Dalcin                                         NULL,
283075648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
2831f4259b30SLisandro Dalcin                                         NULL,
2832f4259b30SLisandro Dalcin                                 /*134*/ NULL,
2833f4259b30SLisandro Dalcin                                         NULL,
2834f4259b30SLisandro Dalcin                                         NULL,
2835f4259b30SLisandro Dalcin                                         NULL,
2836f4259b30SLisandro Dalcin                                         NULL,
2837f4259b30SLisandro Dalcin                                 /*139*/ NULL,
2838f4259b30SLisandro Dalcin                                         NULL,
2839f4259b30SLisandro Dalcin                                         NULL,
2840f4259b30SLisandro Dalcin                                         NULL,
2841f4259b30SLisandro Dalcin                                         NULL,
28424222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
2843f4259b30SLisandro Dalcin                                 /*145*/ NULL,
2844f4259b30SLisandro Dalcin                                         NULL,
2845f4259b30SLisandro Dalcin                                         NULL
2846985db425SBarry Smith };
284790ace30eSBarry Smith 
28484b828684SBarry Smith /*@C
2849fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2850d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2851d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2852289bc588SBarry Smith 
2853d083f849SBarry Smith    Collective
2854db81eaa0SLois Curfman McInnes 
285520563c6bSBarry Smith    Input Parameters:
2856db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
28570c775827SLois Curfman McInnes .  m - number of rows
285818f449edSLois Curfman McInnes .  n - number of columns
28590298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2860dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
286120563c6bSBarry Smith 
286220563c6bSBarry Smith    Output Parameter:
286344cd7ae7SLois Curfman McInnes .  A - the matrix
286420563c6bSBarry Smith 
2865b259b22eSLois Curfman McInnes    Notes:
286618f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
286718f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
28680298fd71SBarry Smith    set data=NULL.
286918f449edSLois Curfman McInnes 
2870027ccd11SLois Curfman McInnes    Level: intermediate
2871027ccd11SLois Curfman McInnes 
287269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
287320563c6bSBarry Smith @*/
28747087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2875289bc588SBarry Smith {
2876dfbe8321SBarry Smith   PetscErrorCode ierr;
28773b2fbd54SBarry Smith 
28783a40ed3dSBarry Smith   PetscFunctionBegin;
2879f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2880f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2881273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2882273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2883273d9f13SBarry Smith   PetscFunctionReturn(0);
2884273d9f13SBarry Smith }
2885273d9f13SBarry Smith 
2886273d9f13SBarry Smith /*@C
2887273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2888273d9f13SBarry Smith 
2889d083f849SBarry Smith    Collective
2890273d9f13SBarry Smith 
2891273d9f13SBarry Smith    Input Parameters:
28921c4f3114SJed Brown +  B - the matrix
28930298fd71SBarry Smith -  data - the array (or NULL)
2894273d9f13SBarry Smith 
2895273d9f13SBarry Smith    Notes:
2896273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2897273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2898284134d9SBarry Smith    need not call this routine.
2899273d9f13SBarry Smith 
2900273d9f13SBarry Smith    Level: intermediate
2901273d9f13SBarry Smith 
2902ad16ce7aSStefano Zampini .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatDenseSetLDA()
2903867c911aSBarry Smith 
2904273d9f13SBarry Smith @*/
29057087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2906273d9f13SBarry Smith {
29074ac538c5SBarry Smith   PetscErrorCode ierr;
2908a23d5eceSKris Buschelman 
2909a23d5eceSKris Buschelman   PetscFunctionBegin;
2910d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
29114ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2912a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2913a23d5eceSKris Buschelman }
2914a23d5eceSKris Buschelman 
29157087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2916a23d5eceSKris Buschelman {
2917ad16ce7aSStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2918dfbe8321SBarry Smith   PetscErrorCode ierr;
2919273d9f13SBarry Smith 
2920273d9f13SBarry Smith   PetscFunctionBegin;
2921616b8fbbSStefano Zampini   if (b->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
2922273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2923a868139aSShri Abhyankar 
292434ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
292534ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
292634ef9618SShri Abhyankar 
2927ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
292886d161a7SShri Abhyankar 
2929ad16ce7aSStefano Zampini   ierr = PetscIntMultError(b->lda,B->cmap->n,NULL);CHKERRQ(ierr);
29309e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
29319e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2932ad16ce7aSStefano Zampini     ierr = PetscCalloc1((size_t)b->lda*B->cmap->n,&b->v);CHKERRQ(ierr);
2933ad16ce7aSStefano Zampini     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*B->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
29342205254eSKarl Rupp 
29359e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2936273d9f13SBarry Smith   } else { /* user-allocated storage */
29379e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2938273d9f13SBarry Smith     b->v          = data;
2939273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2940273d9f13SBarry Smith   }
29410450473dSBarry Smith   B->assembled = PETSC_TRUE;
2942273d9f13SBarry Smith   PetscFunctionReturn(0);
2943273d9f13SBarry Smith }
2944273d9f13SBarry Smith 
294565b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2946cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
29478baccfbdSHong Zhang {
2948d77f618aSHong Zhang   Mat               mat_elemental;
2949d77f618aSHong Zhang   PetscErrorCode    ierr;
29501683a169SBarry Smith   const PetscScalar *array;
29511683a169SBarry Smith   PetscScalar       *v_colwise;
2952d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2953d77f618aSHong Zhang 
29548baccfbdSHong Zhang   PetscFunctionBegin;
2955d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
29561683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&array);CHKERRQ(ierr);
2957d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2958d77f618aSHong Zhang   k = 0;
2959d77f618aSHong Zhang   for (j=0; j<N; j++) {
2960d77f618aSHong Zhang     cols[j] = j;
2961d77f618aSHong Zhang     for (i=0; i<M; i++) {
2962d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2963d77f618aSHong Zhang     }
2964d77f618aSHong Zhang   }
2965d77f618aSHong Zhang   for (i=0; i<M; i++) {
2966d77f618aSHong Zhang     rows[i] = i;
2967d77f618aSHong Zhang   }
29681683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&array);CHKERRQ(ierr);
2969d77f618aSHong Zhang 
2970d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2971d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2972d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2973d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2974d77f618aSHong Zhang 
2975d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2976d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2977d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2978d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2979d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2980d77f618aSHong Zhang 
2981511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
298228be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2983d77f618aSHong Zhang   } else {
2984d77f618aSHong Zhang     *newmat = mat_elemental;
2985d77f618aSHong Zhang   }
29868baccfbdSHong Zhang   PetscFunctionReturn(0);
29878baccfbdSHong Zhang }
298865b80a83SHong Zhang #endif
29898baccfbdSHong Zhang 
299017359960SJose E. Roman PetscErrorCode  MatDenseSetLDA_SeqDense(Mat B,PetscInt lda)
29911b807ce4Svictorle {
29921b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
29937422da62SJose E. Roman   PetscBool    data;
299421a2c019SBarry Smith 
29951b807ce4Svictorle   PetscFunctionBegin;
29967422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
29977422da62SJose E. Roman   if (!b->user_alloc && data && b->lda!=lda) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"LDA cannot be changed after allocation of internal storage");
2998e32f2f54SBarry 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);
29991b807ce4Svictorle   b->lda = lda;
30001b807ce4Svictorle   PetscFunctionReturn(0);
30011b807ce4Svictorle }
30021b807ce4Svictorle 
3003d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
3004d528f656SJakub Kruzik {
3005d528f656SJakub Kruzik   PetscErrorCode ierr;
3006d528f656SJakub Kruzik   PetscMPIInt    size;
3007d528f656SJakub Kruzik 
3008d528f656SJakub Kruzik   PetscFunctionBegin;
3009ffc4695bSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr);
3010d528f656SJakub Kruzik   if (size == 1) {
3011d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
3012d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
3013d528f656SJakub Kruzik     } else {
3014d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
3015d528f656SJakub Kruzik     }
3016d528f656SJakub Kruzik   } else {
3017d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
3018d528f656SJakub Kruzik   }
3019d528f656SJakub Kruzik   PetscFunctionReturn(0);
3020d528f656SJakub Kruzik }
3021d528f656SJakub Kruzik 
30226947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
30236947451fSStefano Zampini {
30246947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
30256947451fSStefano Zampini   PetscErrorCode ierr;
30266947451fSStefano Zampini 
30276947451fSStefano Zampini   PetscFunctionBegin;
30285ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
30295ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
30306947451fSStefano Zampini   if (!a->cvec) {
30316947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
3032616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
30336947451fSStefano Zampini   }
30346947451fSStefano Zampini   a->vecinuse = col + 1;
30356947451fSStefano Zampini   ierr = MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
30366947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
30376947451fSStefano Zampini   *v   = a->cvec;
30386947451fSStefano Zampini   PetscFunctionReturn(0);
30396947451fSStefano Zampini }
30406947451fSStefano Zampini 
30416947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
30426947451fSStefano Zampini {
30436947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
30446947451fSStefano Zampini   PetscErrorCode ierr;
30456947451fSStefano Zampini 
30466947451fSStefano Zampini   PetscFunctionBegin;
30475ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
30486947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
30496947451fSStefano Zampini   a->vecinuse = 0;
30506947451fSStefano Zampini   ierr = MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
30516947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
30526947451fSStefano Zampini   *v   = NULL;
30536947451fSStefano Zampini   PetscFunctionReturn(0);
30546947451fSStefano Zampini }
30556947451fSStefano Zampini 
30566947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
30576947451fSStefano Zampini {
30586947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
30596947451fSStefano Zampini   PetscErrorCode ierr;
30606947451fSStefano Zampini 
30616947451fSStefano Zampini   PetscFunctionBegin;
30625ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
30635ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
30646947451fSStefano Zampini   if (!a->cvec) {
30656947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
3066616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
30676947451fSStefano Zampini   }
30686947451fSStefano Zampini   a->vecinuse = col + 1;
30696947451fSStefano Zampini   ierr = MatDenseGetArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
30706947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
30716947451fSStefano Zampini   ierr = VecLockReadPush(a->cvec);CHKERRQ(ierr);
30726947451fSStefano Zampini   *v   = a->cvec;
30736947451fSStefano Zampini   PetscFunctionReturn(0);
30746947451fSStefano Zampini }
30756947451fSStefano Zampini 
30766947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
30776947451fSStefano Zampini {
30786947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
30796947451fSStefano Zampini   PetscErrorCode ierr;
30806947451fSStefano Zampini 
30816947451fSStefano Zampini   PetscFunctionBegin;
30825ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
30836947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
30846947451fSStefano Zampini   a->vecinuse = 0;
30856947451fSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
30866947451fSStefano Zampini   ierr = VecLockReadPop(a->cvec);CHKERRQ(ierr);
30876947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
30886947451fSStefano Zampini   *v   = NULL;
30896947451fSStefano Zampini   PetscFunctionReturn(0);
30906947451fSStefano Zampini }
30916947451fSStefano Zampini 
30926947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
30936947451fSStefano Zampini {
30946947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
30956947451fSStefano Zampini   PetscErrorCode ierr;
30966947451fSStefano Zampini 
30976947451fSStefano Zampini   PetscFunctionBegin;
30985ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
30995ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
31006947451fSStefano Zampini   if (!a->cvec) {
31016947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
3102616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
31036947451fSStefano Zampini   }
31046947451fSStefano Zampini   a->vecinuse = col + 1;
31056947451fSStefano Zampini   ierr = MatDenseGetArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
31066947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
31076947451fSStefano Zampini   *v   = a->cvec;
31086947451fSStefano Zampini   PetscFunctionReturn(0);
31096947451fSStefano Zampini }
31106947451fSStefano Zampini 
31116947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
31126947451fSStefano Zampini {
31136947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31146947451fSStefano Zampini   PetscErrorCode ierr;
31156947451fSStefano Zampini 
31166947451fSStefano Zampini   PetscFunctionBegin;
31175ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
31186947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
31196947451fSStefano Zampini   a->vecinuse = 0;
31206947451fSStefano Zampini   ierr = MatDenseRestoreArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
31216947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
31226947451fSStefano Zampini   *v   = NULL;
31236947451fSStefano Zampini   PetscFunctionReturn(0);
31246947451fSStefano Zampini }
31256947451fSStefano Zampini 
31265ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
31275ea7661aSPierre Jolivet {
31285ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31295ea7661aSPierre Jolivet   PetscErrorCode ierr;
31305ea7661aSPierre Jolivet 
31315ea7661aSPierre Jolivet   PetscFunctionBegin;
31325ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
31335ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
31345ea7661aSPierre Jolivet   if (a->cmat && cend-cbegin != a->cmat->cmap->N) {
31355ea7661aSPierre Jolivet     ierr = MatDestroy(&a->cmat);CHKERRQ(ierr);
31365ea7661aSPierre Jolivet   }
31375ea7661aSPierre Jolivet   if (!a->cmat) {
3138616b8fbbSStefano Zampini     ierr = MatCreateDense(PetscObjectComm((PetscObject)A),A->rmap->n,PETSC_DECIDE,A->rmap->N,cend-cbegin,(PetscScalar*)a->v + (size_t)cbegin * (size_t)a->lda,&a->cmat);CHKERRQ(ierr);
3139616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cmat);CHKERRQ(ierr);
31405ea7661aSPierre Jolivet   } else {
3141616b8fbbSStefano Zampini     ierr = MatDensePlaceArray(a->cmat,a->v + (size_t)cbegin * (size_t)a->lda);CHKERRQ(ierr);
31425ea7661aSPierre Jolivet   }
3143616b8fbbSStefano Zampini   ierr = MatDenseSetLDA(a->cmat,a->lda);CHKERRQ(ierr);
31445ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
31455ea7661aSPierre Jolivet   *v = a->cmat;
31465ea7661aSPierre Jolivet   PetscFunctionReturn(0);
31475ea7661aSPierre Jolivet }
31485ea7661aSPierre Jolivet 
31495ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A,Mat *v)
31505ea7661aSPierre Jolivet {
31515ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31525ea7661aSPierre Jolivet   PetscErrorCode ierr;
31535ea7661aSPierre Jolivet 
31545ea7661aSPierre Jolivet   PetscFunctionBegin;
31555ea7661aSPierre Jolivet   if (!a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetSubMatrix() first");
31565ea7661aSPierre Jolivet   if (!a->cmat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column matrix");
3157616b8fbbSStefano Zampini   if (*v != a->cmat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not the matrix obtained from MatDenseGetSubMatrix()");
31585ea7661aSPierre Jolivet   a->matinuse = 0;
31595ea7661aSPierre Jolivet   ierr = MatDenseResetArray(a->cmat);CHKERRQ(ierr);
31605ea7661aSPierre Jolivet   *v   = NULL;
31615ea7661aSPierre Jolivet   PetscFunctionReturn(0);
31625ea7661aSPierre Jolivet }
31635ea7661aSPierre Jolivet 
31640bad9183SKris Buschelman /*MC
3165fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
31660bad9183SKris Buschelman 
31670bad9183SKris Buschelman    Options Database Keys:
31680bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
31690bad9183SKris Buschelman 
31700bad9183SKris Buschelman   Level: beginner
31710bad9183SKris Buschelman 
317289665df3SBarry Smith .seealso: MatCreateSeqDense()
317389665df3SBarry Smith 
31740bad9183SKris Buschelman M*/
3175ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
3176273d9f13SBarry Smith {
3177273d9f13SBarry Smith   Mat_SeqDense   *b;
3178dfbe8321SBarry Smith   PetscErrorCode ierr;
31797c334f02SBarry Smith   PetscMPIInt    size;
3180273d9f13SBarry Smith 
3181273d9f13SBarry Smith   PetscFunctionBegin;
3182ffc4695bSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRMPI(ierr);
3183e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
318455659b69SBarry Smith 
3185b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
3186549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
318744cd7ae7SLois Curfman McInnes   B->data = (void*)b;
318818f449edSLois Curfman McInnes 
3189273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
31904e220ebcSLois Curfman McInnes 
3191*4905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)B,"MatQRFactor_C",MatQRFactor_SeqDense);CHKERRQ(ierr);
3192*4905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)B,"MatQRFactorNumeric_C",MatQRFactorNumeric_SeqDense);CHKERRQ(ierr);
3193*4905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)B,"MatQRFactorSymbolic_C",MatQRFactorSymbolic_SeqDense);CHKERRQ(ierr);
319449a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
3195ad16ce7aSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseSetLDA_C",MatDenseSetLDA_SeqDense);CHKERRQ(ierr);
3196bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
31978572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
3198d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
3199d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
3200d5ea218eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseReplaceArray_C",MatDenseReplaceArray_SeqDense);CHKERRQ(ierr);
32018572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
3202715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
32036947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayWrite_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
32046947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayWrite_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
3205bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
32068baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
32078baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
32088baccfbdSHong Zhang #endif
3209d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
3210d24d4204SJose E. Roman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_scalapack_C",MatConvert_Dense_ScaLAPACK);CHKERRQ(ierr);
3211d24d4204SJose E. Roman #endif
32122bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
32132bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA);CHKERRQ(ierr);
32144222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
32154222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
3216637a0070SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
32172bf066beSStefano Zampini #endif
3218bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
32194222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
32204222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
32214222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
32224222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
322396e6d5c4SRichard Tran Mills 
3224af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
3225af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
32266947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVec_C",MatDenseGetColumnVec_SeqDense);CHKERRQ(ierr);
32276947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVec_C",MatDenseRestoreColumnVec_SeqDense);CHKERRQ(ierr);
32286947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecRead_C",MatDenseGetColumnVecRead_SeqDense);CHKERRQ(ierr);
32296947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecRead_C",MatDenseRestoreColumnVecRead_SeqDense);CHKERRQ(ierr);
32306947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecWrite_C",MatDenseGetColumnVecWrite_SeqDense);CHKERRQ(ierr);
32316947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecWrite_C",MatDenseRestoreColumnVecWrite_SeqDense);CHKERRQ(ierr);
32325ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetSubMatrix_C",MatDenseGetSubMatrix_SeqDense);CHKERRQ(ierr);
32335ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreSubMatrix_C",MatDenseRestoreSubMatrix_SeqDense);CHKERRQ(ierr);
323417667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
32353a40ed3dSBarry Smith   PetscFunctionReturn(0);
3236289bc588SBarry Smith }
323786aefd0dSHong Zhang 
323886aefd0dSHong Zhang /*@C
3239af53bab2SHong 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.
324086aefd0dSHong Zhang 
324186aefd0dSHong Zhang    Not Collective
324286aefd0dSHong Zhang 
32435ea7661aSPierre Jolivet    Input Parameters:
324486aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
324586aefd0dSHong Zhang -  col - column index
324686aefd0dSHong Zhang 
324786aefd0dSHong Zhang    Output Parameter:
324886aefd0dSHong Zhang .  vals - pointer to the data
324986aefd0dSHong Zhang 
325086aefd0dSHong Zhang    Level: intermediate
325186aefd0dSHong Zhang 
325286aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
325386aefd0dSHong Zhang @*/
325486aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
325586aefd0dSHong Zhang {
325686aefd0dSHong Zhang   PetscErrorCode ierr;
325786aefd0dSHong Zhang 
325886aefd0dSHong Zhang   PetscFunctionBegin;
3259d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3260d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3261d5ea218eSStefano Zampini   PetscValidPointer(vals,3);
326286aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
326386aefd0dSHong Zhang   PetscFunctionReturn(0);
326486aefd0dSHong Zhang }
326586aefd0dSHong Zhang 
326686aefd0dSHong Zhang /*@C
326786aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
326886aefd0dSHong Zhang 
326986aefd0dSHong Zhang    Not Collective
327086aefd0dSHong Zhang 
327186aefd0dSHong Zhang    Input Parameter:
327286aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
327386aefd0dSHong Zhang 
327486aefd0dSHong Zhang    Output Parameter:
327586aefd0dSHong Zhang .  vals - pointer to the data
327686aefd0dSHong Zhang 
327786aefd0dSHong Zhang    Level: intermediate
327886aefd0dSHong Zhang 
327986aefd0dSHong Zhang .seealso: MatDenseGetColumn()
328086aefd0dSHong Zhang @*/
328186aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
328286aefd0dSHong Zhang {
328386aefd0dSHong Zhang   PetscErrorCode ierr;
328486aefd0dSHong Zhang 
328586aefd0dSHong Zhang   PetscFunctionBegin;
3286d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3287d5ea218eSStefano Zampini   PetscValidPointer(vals,2);
328886aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
328986aefd0dSHong Zhang   PetscFunctionReturn(0);
329086aefd0dSHong Zhang }
32916947451fSStefano Zampini 
32926947451fSStefano Zampini /*@C
32936947451fSStefano Zampini    MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec.
32946947451fSStefano Zampini 
32956947451fSStefano Zampini    Collective
32966947451fSStefano Zampini 
32975ea7661aSPierre Jolivet    Input Parameters:
32986947451fSStefano Zampini +  mat - the Mat object
32996947451fSStefano Zampini -  col - the column index
33006947451fSStefano Zampini 
33016947451fSStefano Zampini    Output Parameter:
33026947451fSStefano Zampini .  v - the vector
33036947451fSStefano Zampini 
33046947451fSStefano Zampini    Notes:
33056947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed.
33066947451fSStefano Zampini      Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access.
33076947451fSStefano Zampini 
33086947451fSStefano Zampini    Level: intermediate
33096947451fSStefano Zampini 
33106947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
33116947451fSStefano Zampini @*/
33126947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec(Mat A,PetscInt col,Vec *v)
33136947451fSStefano Zampini {
33146947451fSStefano Zampini   PetscErrorCode ierr;
33156947451fSStefano Zampini 
33166947451fSStefano Zampini   PetscFunctionBegin;
33176947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
33186947451fSStefano Zampini   PetscValidType(A,1);
33196947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
33206947451fSStefano Zampini   PetscValidPointer(v,3);
33216947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
33226947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
33236947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
33246947451fSStefano Zampini   PetscFunctionReturn(0);
33256947451fSStefano Zampini }
33266947451fSStefano Zampini 
33276947451fSStefano Zampini /*@C
33286947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
33296947451fSStefano Zampini 
33306947451fSStefano Zampini    Collective
33316947451fSStefano Zampini 
33325ea7661aSPierre Jolivet    Input Parameters:
33336947451fSStefano Zampini +  mat - the Mat object
33346947451fSStefano Zampini .  col - the column index
33356947451fSStefano Zampini -  v - the Vec object
33366947451fSStefano Zampini 
33376947451fSStefano Zampini    Level: intermediate
33386947451fSStefano Zampini 
33396947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
33406947451fSStefano Zampini @*/
33416947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec *v)
33426947451fSStefano Zampini {
33436947451fSStefano Zampini   PetscErrorCode ierr;
33446947451fSStefano Zampini 
33456947451fSStefano Zampini   PetscFunctionBegin;
33466947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
33476947451fSStefano Zampini   PetscValidType(A,1);
33486947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
33496947451fSStefano Zampini   PetscValidPointer(v,3);
33506947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
33516947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
33526947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
33536947451fSStefano Zampini   PetscFunctionReturn(0);
33546947451fSStefano Zampini }
33556947451fSStefano Zampini 
33566947451fSStefano Zampini /*@C
33576947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
33586947451fSStefano Zampini 
33596947451fSStefano Zampini    Collective
33606947451fSStefano Zampini 
33615ea7661aSPierre Jolivet    Input Parameters:
33626947451fSStefano Zampini +  mat - the Mat object
33636947451fSStefano Zampini -  col - the column index
33646947451fSStefano Zampini 
33656947451fSStefano Zampini    Output Parameter:
33666947451fSStefano Zampini .  v - the vector
33676947451fSStefano Zampini 
33686947451fSStefano Zampini    Notes:
33696947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
33706947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
33716947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
33726947451fSStefano Zampini 
33736947451fSStefano Zampini    Level: intermediate
33746947451fSStefano Zampini 
33756947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
33766947451fSStefano Zampini @*/
33776947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec *v)
33786947451fSStefano Zampini {
33796947451fSStefano Zampini   PetscErrorCode ierr;
33806947451fSStefano Zampini 
33816947451fSStefano Zampini   PetscFunctionBegin;
33826947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
33836947451fSStefano Zampini   PetscValidType(A,1);
33846947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
33856947451fSStefano Zampini   PetscValidPointer(v,3);
33866947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
33876947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
33886947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
33896947451fSStefano Zampini   PetscFunctionReturn(0);
33906947451fSStefano Zampini }
33916947451fSStefano Zampini 
33926947451fSStefano Zampini /*@C
33936947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
33946947451fSStefano Zampini 
33956947451fSStefano Zampini    Collective
33966947451fSStefano Zampini 
33975ea7661aSPierre Jolivet    Input Parameters:
33986947451fSStefano Zampini +  mat - the Mat object
33996947451fSStefano Zampini .  col - the column index
34006947451fSStefano Zampini -  v - the Vec object
34016947451fSStefano Zampini 
34026947451fSStefano Zampini    Level: intermediate
34036947451fSStefano Zampini 
34046947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecWrite()
34056947451fSStefano Zampini @*/
34066947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec *v)
34076947451fSStefano Zampini {
34086947451fSStefano Zampini   PetscErrorCode ierr;
34096947451fSStefano Zampini 
34106947451fSStefano Zampini   PetscFunctionBegin;
34116947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34126947451fSStefano Zampini   PetscValidType(A,1);
34136947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
34146947451fSStefano Zampini   PetscValidPointer(v,3);
34156947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
34166947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
34176947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
34186947451fSStefano Zampini   PetscFunctionReturn(0);
34196947451fSStefano Zampini }
34206947451fSStefano Zampini 
34216947451fSStefano Zampini /*@C
34226947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
34236947451fSStefano Zampini 
34246947451fSStefano Zampini    Collective
34256947451fSStefano Zampini 
34265ea7661aSPierre Jolivet    Input Parameters:
34276947451fSStefano Zampini +  mat - the Mat object
34286947451fSStefano Zampini -  col - the column index
34296947451fSStefano Zampini 
34306947451fSStefano Zampini    Output Parameter:
34316947451fSStefano Zampini .  v - the vector
34326947451fSStefano Zampini 
34336947451fSStefano Zampini    Notes:
34346947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
34356947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
34366947451fSStefano Zampini 
34376947451fSStefano Zampini    Level: intermediate
34386947451fSStefano Zampini 
34396947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
34406947451fSStefano Zampini @*/
34416947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec *v)
34426947451fSStefano Zampini {
34436947451fSStefano Zampini   PetscErrorCode ierr;
34446947451fSStefano Zampini 
34456947451fSStefano Zampini   PetscFunctionBegin;
34466947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34476947451fSStefano Zampini   PetscValidType(A,1);
34486947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
34496947451fSStefano Zampini   PetscValidPointer(v,3);
34506947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
34516947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
34526947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
34536947451fSStefano Zampini   PetscFunctionReturn(0);
34546947451fSStefano Zampini }
34556947451fSStefano Zampini 
34566947451fSStefano Zampini /*@C
34576947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
34586947451fSStefano Zampini 
34596947451fSStefano Zampini    Collective
34606947451fSStefano Zampini 
34615ea7661aSPierre Jolivet    Input Parameters:
34626947451fSStefano Zampini +  mat - the Mat object
34636947451fSStefano Zampini .  col - the column index
34646947451fSStefano Zampini -  v - the Vec object
34656947451fSStefano Zampini 
34666947451fSStefano Zampini    Level: intermediate
34676947451fSStefano Zampini 
34686947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead()
34696947451fSStefano Zampini @*/
34706947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec *v)
34716947451fSStefano Zampini {
34726947451fSStefano Zampini   PetscErrorCode ierr;
34736947451fSStefano Zampini 
34746947451fSStefano Zampini   PetscFunctionBegin;
34756947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34766947451fSStefano Zampini   PetscValidType(A,1);
34776947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
34786947451fSStefano Zampini   PetscValidPointer(v,3);
34796947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
34806947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
34816947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
34826947451fSStefano Zampini   PetscFunctionReturn(0);
34836947451fSStefano Zampini }
34845ea7661aSPierre Jolivet 
34855ea7661aSPierre Jolivet /*@C
34865ea7661aSPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of columns of a dense matrix, represented as a Mat.
34875ea7661aSPierre Jolivet 
34885ea7661aSPierre Jolivet    Collective
34895ea7661aSPierre Jolivet 
34905ea7661aSPierre Jolivet    Input Parameters:
34915ea7661aSPierre Jolivet +  mat - the Mat object
34925ea7661aSPierre Jolivet .  cbegin - the first index in the block
34935ea7661aSPierre Jolivet -  cend - the last index in the block
34945ea7661aSPierre Jolivet 
34955ea7661aSPierre Jolivet    Output Parameter:
34965ea7661aSPierre Jolivet .  v - the matrix
34975ea7661aSPierre Jolivet 
34985ea7661aSPierre Jolivet    Notes:
34995ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
35005ea7661aSPierre Jolivet 
35015ea7661aSPierre Jolivet    Level: intermediate
35025ea7661aSPierre Jolivet 
35035ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseRestoreSubMatrix()
35045ea7661aSPierre Jolivet @*/
35055ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
35065ea7661aSPierre Jolivet {
35075ea7661aSPierre Jolivet   PetscErrorCode ierr;
35085ea7661aSPierre Jolivet 
35095ea7661aSPierre Jolivet   PetscFunctionBegin;
35105ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35115ea7661aSPierre Jolivet   PetscValidType(A,1);
35125ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cbegin,2);
35135ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cend,3);
35145ea7661aSPierre Jolivet   PetscValidPointer(v,4);
35155ea7661aSPierre Jolivet   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35165ea7661aSPierre Jolivet   if (cbegin < 0 || cbegin > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid cbegin %D, should be in [0,%D)",cbegin,A->cmap->N);
3517616b8fbbSStefano Zampini   if (cend < cbegin || cend > A->cmap->N) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid cend %D, should be in [%D,%D)",cend,cbegin,A->cmap->N);
35185ea7661aSPierre Jolivet   ierr = PetscUseMethod(A,"MatDenseGetSubMatrix_C",(Mat,PetscInt,PetscInt,Mat*),(A,cbegin,cend,v));CHKERRQ(ierr);
35195ea7661aSPierre Jolivet   PetscFunctionReturn(0);
35205ea7661aSPierre Jolivet }
35215ea7661aSPierre Jolivet 
35225ea7661aSPierre Jolivet /*@C
35235ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
35245ea7661aSPierre Jolivet 
35255ea7661aSPierre Jolivet    Collective
35265ea7661aSPierre Jolivet 
35275ea7661aSPierre Jolivet    Input Parameters:
35285ea7661aSPierre Jolivet +  mat - the Mat object
35295ea7661aSPierre Jolivet -  v - the Mat object
35305ea7661aSPierre Jolivet 
35315ea7661aSPierre Jolivet    Level: intermediate
35325ea7661aSPierre Jolivet 
35335ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseGetSubMatrix()
35345ea7661aSPierre Jolivet @*/
35355ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix(Mat A,Mat *v)
35365ea7661aSPierre Jolivet {
35375ea7661aSPierre Jolivet   PetscErrorCode ierr;
35385ea7661aSPierre Jolivet 
35395ea7661aSPierre Jolivet   PetscFunctionBegin;
35405ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35415ea7661aSPierre Jolivet   PetscValidType(A,1);
35425ea7661aSPierre Jolivet   PetscValidPointer(v,2);
35435ea7661aSPierre Jolivet   ierr = PetscUseMethod(A,"MatDenseRestoreSubMatrix_C",(Mat,Mat*),(A,v));CHKERRQ(ierr);
35445ea7661aSPierre Jolivet   PetscFunctionReturn(0);
35455ea7661aSPierre Jolivet }
3546