xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 4396437d7f67f9fe41f15190ecbfe4af75f5cbcd)
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 
441*4396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt xlda, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
442289bc588SBarry Smith {
443c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
444*4396437dSToby Isaac   PetscBLASInt    info;
4456849ba73SBarry Smith   PetscErrorCode  ierr;
44667e560aaSBarry Smith 
4473a40ed3dSBarry Smith   PetscFunctionBegin;
44800121966SStefano Zampini   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
449*4396437dSToby Isaac   PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_(T ? "T" : "N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
45000121966SStefano Zampini   ierr = PetscFPTrapPop();CHKERRQ(ierr);
45185e2c93fSHong Zhang   if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
4524905a7bcSToby Isaac   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
453*4396437dSToby Isaac   PetscFunctionReturn(0);
454*4396437dSToby Isaac }
455*4396437dSToby Isaac 
456*4396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat);
457*4396437dSToby Isaac 
458*4396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt xlda, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
459*4396437dSToby Isaac {
460*4396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
461*4396437dSToby Isaac   PetscBLASInt    info;
462*4396437dSToby Isaac   PetscErrorCode  ierr;
463*4396437dSToby Isaac 
464*4396437dSToby Isaac   PetscFunctionBegin;
465a49dc2a2SStefano Zampini   if (A->spd) {
466*4396437dSToby Isaac     if (PetscDefined(USE_COMPLEX) && T) {ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);}
46700121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4688b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
46900121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
47085e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
471*4396437dSToby Isaac     if (PetscDefined(USE_COMPLEX) && T) {ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);}
472a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
473a49dc2a2SStefano Zampini   } else if (A->hermitian) {
474*4396437dSToby Isaac     if (T) {ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);}
47500121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
476a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
47700121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
478a49dc2a2SStefano Zampini     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
479*4396437dSToby Isaac     if (T) {ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);}
480a49dc2a2SStefano Zampini #endif
481a49dc2a2SStefano Zampini   } else { /* symmetric case */
48200121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
483a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
48400121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
485a49dc2a2SStefano Zampini     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
486a49dc2a2SStefano Zampini   }
4874905a7bcSToby Isaac   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
488*4396437dSToby Isaac   PetscFunctionReturn(0);
489*4396437dSToby Isaac }
49085e2c93fSHong Zhang 
491*4396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt xlda, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
492*4396437dSToby Isaac {
493*4396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
494*4396437dSToby Isaac   PetscBLASInt    info;
495*4396437dSToby Isaac   char            trans;
496*4396437dSToby Isaac   PetscErrorCode  ierr;
497*4396437dSToby Isaac 
498*4396437dSToby Isaac   PetscFunctionBegin;
4994905a7bcSToby Isaac   if (PetscDefined(USE_COMPLEX)) {
5004905a7bcSToby Isaac     trans = 'C';
5014905a7bcSToby Isaac   } else {
5024905a7bcSToby Isaac     trans = 'T';
5034905a7bcSToby Isaac   }
5044905a7bcSToby Isaac   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5054905a7bcSToby Isaac   PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", &trans, &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&xlda,mat->fwork,&mat->lfwork,&info));
5064905a7bcSToby Isaac   ierr = PetscFPTrapPop();CHKERRQ(ierr);
5074905a7bcSToby Isaac   if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform");
5084905a7bcSToby Isaac   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5094905a7bcSToby Isaac   PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "N", "N", &mat->rank,&nrhs,mat->v,&mat->lda,x,&xlda,&info));
5104905a7bcSToby Isaac   ierr = PetscFPTrapPop();CHKERRQ(ierr);
5114905a7bcSToby Isaac   if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve");
5124905a7bcSToby Isaac   for (PetscInt j = 0; j < nrhs; j++) {
5134905a7bcSToby Isaac     for (PetscInt i = mat->rank; i < k; i++) {
5144905a7bcSToby Isaac       x[j*xlda + i] = 0.;
5154905a7bcSToby Isaac     }
5164905a7bcSToby Isaac   }
5174905a7bcSToby Isaac   ierr = PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank)));CHKERRQ(ierr);
5184905a7bcSToby Isaac   PetscFunctionReturn(0);
5194905a7bcSToby Isaac }
5204905a7bcSToby Isaac 
521*4396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt xlda, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
5224905a7bcSToby Isaac {
523*4396437dSToby Isaac   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
524*4396437dSToby Isaac   PetscBLASInt      info;
5254905a7bcSToby Isaac   PetscErrorCode    ierr;
526*4396437dSToby Isaac 
527*4396437dSToby Isaac   PetscFunctionBegin;
528*4396437dSToby Isaac   if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
529*4396437dSToby Isaac     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
530*4396437dSToby Isaac     PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "T", "N", &m,&nrhs,mat->v,&mat->lda,x,&xlda,&info));
531*4396437dSToby Isaac     ierr = PetscFPTrapPop();CHKERRQ(ierr);
532*4396437dSToby Isaac     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve");
533*4396437dSToby Isaac     if (PetscDefined(USE_COMPLEX)) {ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);}
534*4396437dSToby Isaac     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
535*4396437dSToby Isaac     PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", "N", &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&xlda,mat->fwork,&mat->lfwork,&info));
536*4396437dSToby Isaac     ierr = PetscFPTrapPop();CHKERRQ(ierr);
537*4396437dSToby Isaac     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform");
538*4396437dSToby Isaac     if (PetscDefined(USE_COMPLEX)) {ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);}
539*4396437dSToby Isaac   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"QR factored matrix cannot be used for transpose solve");
540*4396437dSToby Isaac   ierr = PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank)));CHKERRQ(ierr);
541*4396437dSToby Isaac   PetscFunctionReturn(0);
542*4396437dSToby Isaac }
543*4396437dSToby Isaac 
544*4396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
545*4396437dSToby Isaac {
546*4396437dSToby Isaac   Mat_SeqDense      *mat = (Mat_SeqDense *) A->data;
5474905a7bcSToby Isaac   PetscScalar       *y;
5484905a7bcSToby Isaac   PetscBLASInt      m=0, k=0;
549*4396437dSToby Isaac   PetscErrorCode    ierr;
5504905a7bcSToby Isaac 
5514905a7bcSToby Isaac   PetscFunctionBegin;
5524905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
5534905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
5544905a7bcSToby Isaac   if (k < m) {
555*4396437dSToby Isaac     ierr = VecCopy(xx, mat->qrrhs);CHKERRQ(ierr);
556*4396437dSToby Isaac     ierr = VecGetArray(mat->qrrhs,&y);CHKERRQ(ierr);
5574905a7bcSToby Isaac   } else {
558*4396437dSToby Isaac     ierr = VecCopy(xx, yy);CHKERRQ(ierr);
5594905a7bcSToby Isaac     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
5604905a7bcSToby Isaac   }
561*4396437dSToby Isaac   *_y = y;
562*4396437dSToby Isaac   *_k = k;
563*4396437dSToby Isaac   *_m = m;
564*4396437dSToby Isaac   PetscFunctionReturn(0);
565*4396437dSToby Isaac }
566*4396437dSToby Isaac 
567*4396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
568*4396437dSToby Isaac {
569*4396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
570*4396437dSToby Isaac   PetscScalar    *y;
571*4396437dSToby Isaac   PetscBLASInt   m, k;
572*4396437dSToby Isaac   PetscErrorCode ierr;
573*4396437dSToby Isaac 
574*4396437dSToby Isaac   PetscFunctionBegin;
575*4396437dSToby Isaac   y   = *_y;
576*4396437dSToby Isaac   *_y = NULL;
577*4396437dSToby Isaac   k   = *_k;
578*4396437dSToby Isaac   m   = *_m;
5794905a7bcSToby Isaac   if (k < m) {
5804905a7bcSToby Isaac     PetscScalar *yv;
5814905a7bcSToby Isaac     ierr = VecGetArray(yy,&yv);CHKERRQ(ierr);
5824905a7bcSToby Isaac     ierr = PetscArraycpy(yv, y, k);CHKERRQ(ierr);
5834905a7bcSToby Isaac     ierr = VecRestoreArray(yy,&yv);CHKERRQ(ierr);
584*4396437dSToby Isaac     ierr = VecRestoreArray(mat->qrrhs, &y);CHKERRQ(ierr);
5854905a7bcSToby Isaac   } else {
5864905a7bcSToby Isaac     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
5874905a7bcSToby Isaac   }
5884905a7bcSToby Isaac   PetscFunctionReturn(0);
5894905a7bcSToby Isaac }
5904905a7bcSToby Isaac 
591*4396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy)
592*4396437dSToby Isaac {
593*4396437dSToby Isaac   PetscScalar    *y;
594*4396437dSToby Isaac   PetscBLASInt   m, k;
595*4396437dSToby Isaac   PetscErrorCode ierr;
596*4396437dSToby Isaac 
597*4396437dSToby Isaac   PetscFunctionBegin;
598*4396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
599*4396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE);CHKERRQ(ierr);
600*4396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
601*4396437dSToby Isaac   PetscFunctionReturn(0);
602*4396437dSToby Isaac }
603*4396437dSToby Isaac 
604*4396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy)
605*4396437dSToby Isaac {
606*4396437dSToby Isaac   PetscScalar    *y;
607*4396437dSToby Isaac   PetscBLASInt   m, k;
608*4396437dSToby Isaac   PetscErrorCode ierr;
609*4396437dSToby Isaac 
610*4396437dSToby Isaac   PetscFunctionBegin;
611*4396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
612*4396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE);CHKERRQ(ierr);
613*4396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
614*4396437dSToby Isaac   PetscFunctionReturn(0);
615*4396437dSToby Isaac }
616*4396437dSToby Isaac 
617*4396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
618*4396437dSToby Isaac {
619*4396437dSToby Isaac   PetscScalar    *y;
620*4396437dSToby Isaac   PetscBLASInt   m, k;
621*4396437dSToby Isaac   PetscErrorCode ierr;
622*4396437dSToby Isaac 
623*4396437dSToby Isaac   PetscFunctionBegin;
624*4396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
625*4396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE);CHKERRQ(ierr);
626*4396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
627*4396437dSToby Isaac   PetscFunctionReturn(0);
628*4396437dSToby Isaac }
629*4396437dSToby Isaac 
630*4396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
631*4396437dSToby Isaac {
632*4396437dSToby Isaac   PetscScalar    *y;
633*4396437dSToby Isaac   PetscBLASInt   m, k;
634*4396437dSToby Isaac   PetscErrorCode ierr;
635*4396437dSToby Isaac 
636*4396437dSToby Isaac   PetscFunctionBegin;
637*4396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
638*4396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE);CHKERRQ(ierr);
639*4396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
640*4396437dSToby Isaac   PetscFunctionReturn(0);
641*4396437dSToby Isaac }
642*4396437dSToby Isaac 
643*4396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy)
644*4396437dSToby Isaac {
645*4396437dSToby Isaac   PetscScalar    *y;
646*4396437dSToby Isaac   PetscBLASInt   m, k;
647*4396437dSToby Isaac   PetscErrorCode ierr;
648*4396437dSToby Isaac 
649*4396437dSToby Isaac   PetscFunctionBegin;
650*4396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
651*4396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k);CHKERRQ(ierr);
652*4396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
653*4396437dSToby Isaac   PetscFunctionReturn(0);
654*4396437dSToby Isaac }
655*4396437dSToby Isaac 
656*4396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy)
657*4396437dSToby Isaac {
658*4396437dSToby Isaac   PetscScalar    *y;
659*4396437dSToby Isaac   PetscBLASInt   m, k;
660*4396437dSToby Isaac   PetscErrorCode ierr;
661*4396437dSToby Isaac 
662*4396437dSToby Isaac   PetscFunctionBegin;
663*4396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
664*4396437dSToby Isaac   ierr = MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k);CHKERRQ(ierr);
665*4396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
666*4396437dSToby Isaac   PetscFunctionReturn(0);
667*4396437dSToby Isaac }
668*4396437dSToby Isaac 
669*4396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ylda, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
6704905a7bcSToby Isaac {
6714905a7bcSToby Isaac   PetscErrorCode    ierr;
6724905a7bcSToby Isaac   const PetscScalar *b;
673*4396437dSToby Isaac   PetscScalar       *y;
6744905a7bcSToby Isaac   PetscInt          n, _blda, _xlda;
675*4396437dSToby Isaac   PetscBLASInt      nrhs=0,m=0,k=0,blda=0,xlda=0,ylda=0;
6764905a7bcSToby Isaac 
6774905a7bcSToby Isaac   PetscFunctionBegin;
6784905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
6794905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
6804905a7bcSToby Isaac   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
6814905a7bcSToby Isaac   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
6824905a7bcSToby Isaac   ierr = MatDenseGetLDA(B,&_blda);CHKERRQ(ierr);
6834905a7bcSToby Isaac   ierr = PetscBLASIntCast(_blda, &blda);CHKERRQ(ierr);
6844905a7bcSToby Isaac   ierr = MatDenseGetLDA(X,&_xlda);CHKERRQ(ierr);
6854905a7bcSToby Isaac   ierr = PetscBLASIntCast(_xlda, &xlda);CHKERRQ(ierr);
6864905a7bcSToby Isaac   if (xlda < m) {
687*4396437dSToby Isaac     ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
688*4396437dSToby Isaac     ierr = PetscMalloc1(nrhs * m, &y);CHKERRQ(ierr);
6894905a7bcSToby Isaac     if (blda == m) {
690*4396437dSToby Isaac       ierr = PetscArraycpy(y,b,blda*nrhs);CHKERRQ(ierr);
6914905a7bcSToby Isaac     } else {
6924905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
693*4396437dSToby Isaac         ierr = PetscArraycpy(&y[j*m],&b[j*blda],m);CHKERRQ(ierr);
6944905a7bcSToby Isaac       }
6954905a7bcSToby Isaac     }
696*4396437dSToby Isaac     ylda = m;
697*4396437dSToby Isaac     ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
6984905a7bcSToby Isaac   } else {
6994905a7bcSToby Isaac     if (blda == xlda) {
700*4396437dSToby Isaac       ierr = MatCopy(B, X, SAME_NONZERO_PATTERN);CHKERRQ(ierr);
701*4396437dSToby Isaac       ierr = MatDenseGetArray(X,&y);CHKERRQ(ierr);
7024905a7bcSToby Isaac     } else {
703*4396437dSToby Isaac       ierr = MatDenseGetArray(X,&y);CHKERRQ(ierr);
704*4396437dSToby Isaac       ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
7054905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
706*4396437dSToby Isaac         ierr = PetscArraycpy(&y[j*xlda],&b[j*blda],m);CHKERRQ(ierr);
7074905a7bcSToby Isaac       }
708*4396437dSToby Isaac       ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
7094905a7bcSToby Isaac     }
710*4396437dSToby Isaac     ylda = xlda;
7114905a7bcSToby Isaac   }
712*4396437dSToby Isaac   *_y    = y;
713*4396437dSToby Isaac   *_ylda = ylda;
714*4396437dSToby Isaac   *_k    = k;
715*4396437dSToby Isaac   *_m    = m;
716*4396437dSToby Isaac   *_nrhs = nrhs;
717*4396437dSToby Isaac   PetscFunctionReturn(0);
718*4396437dSToby Isaac }
719*4396437dSToby Isaac 
720*4396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ylda, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
721*4396437dSToby Isaac {
722*4396437dSToby Isaac   PetscScalar       *y;
723*4396437dSToby Isaac   PetscInt          _xlda;
724*4396437dSToby Isaac   PetscBLASInt      k,ylda,nrhs,xlda=0;
725*4396437dSToby Isaac   PetscErrorCode    ierr;
726*4396437dSToby Isaac 
727*4396437dSToby Isaac   PetscFunctionBegin;
728*4396437dSToby Isaac   y    = *_y;
729*4396437dSToby Isaac   *_y  = NULL;
730*4396437dSToby Isaac   k    = *_k;
731*4396437dSToby Isaac   ylda = *_ylda;
732*4396437dSToby Isaac   nrhs = *_nrhs;
733*4396437dSToby Isaac   ierr = MatDenseGetLDA(X,&_xlda);CHKERRQ(ierr);
734*4396437dSToby Isaac   ierr = PetscBLASIntCast(_xlda, &xlda);CHKERRQ(ierr);
735*4396437dSToby Isaac   if (xlda != ylda) {
7364905a7bcSToby Isaac     PetscScalar *xv;
7374905a7bcSToby Isaac     ierr = MatDenseGetArray(X,&xv);CHKERRQ(ierr);
7384905a7bcSToby Isaac     for (PetscInt j = 0; j < nrhs; j++) {
739*4396437dSToby Isaac       ierr = PetscArraycpy(&xv[j*xlda],&y[j*ylda],k);CHKERRQ(ierr);
7404905a7bcSToby Isaac     }
7414905a7bcSToby Isaac     ierr = MatDenseRestoreArray(X,&xv);CHKERRQ(ierr);
742*4396437dSToby Isaac     ierr = PetscFree(y);CHKERRQ(ierr);
7434905a7bcSToby Isaac   } else {
744*4396437dSToby Isaac     ierr = MatDenseRestoreArray(X,&y);CHKERRQ(ierr);
7454905a7bcSToby Isaac   }
74685e2c93fSHong Zhang   PetscFunctionReturn(0);
74785e2c93fSHong Zhang }
74885e2c93fSHong Zhang 
749*4396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X)
750*4396437dSToby Isaac {
751*4396437dSToby Isaac   PetscScalar    *y;
752*4396437dSToby Isaac   PetscBLASInt   m, k, ylda, nrhs;
753*4396437dSToby Isaac   PetscErrorCode ierr;
754*4396437dSToby Isaac 
755*4396437dSToby Isaac   PetscFunctionBegin;
756*4396437dSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
757*4396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_LU(A, y, ylda, m, nrhs, k, PETSC_FALSE);CHKERRQ(ierr);
758*4396437dSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
759*4396437dSToby Isaac   PetscFunctionReturn(0);
760*4396437dSToby Isaac }
761*4396437dSToby Isaac 
762*4396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X)
763*4396437dSToby Isaac {
764*4396437dSToby Isaac   PetscScalar    *y;
765*4396437dSToby Isaac   PetscBLASInt   m, k, ylda, nrhs;
766*4396437dSToby Isaac   PetscErrorCode ierr;
767*4396437dSToby Isaac 
768*4396437dSToby Isaac   PetscFunctionBegin;
769*4396437dSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
770*4396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_LU(A, y, ylda, m, nrhs, k, PETSC_TRUE);CHKERRQ(ierr);
771*4396437dSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
772*4396437dSToby Isaac   PetscFunctionReturn(0);
773*4396437dSToby Isaac }
774*4396437dSToby Isaac 
775*4396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X)
776*4396437dSToby Isaac {
777*4396437dSToby Isaac   PetscScalar    *y;
778*4396437dSToby Isaac   PetscBLASInt   m, k, ylda, nrhs;
779*4396437dSToby Isaac   PetscErrorCode ierr;
780*4396437dSToby Isaac 
781*4396437dSToby Isaac   PetscFunctionBegin;
782*4396437dSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
783*4396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_Cholesky(A, y, ylda, m, nrhs, k, PETSC_FALSE);CHKERRQ(ierr);
784*4396437dSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
785*4396437dSToby Isaac   PetscFunctionReturn(0);
786*4396437dSToby Isaac }
787*4396437dSToby Isaac 
788*4396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X)
789*4396437dSToby Isaac {
790*4396437dSToby Isaac   PetscScalar    *y;
791*4396437dSToby Isaac   PetscBLASInt   m, k, ylda, nrhs;
792*4396437dSToby Isaac   PetscErrorCode ierr;
793*4396437dSToby Isaac 
794*4396437dSToby Isaac   PetscFunctionBegin;
795*4396437dSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
796*4396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_Cholesky(A, y, ylda, m, nrhs, k, PETSC_TRUE);CHKERRQ(ierr);
797*4396437dSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
798*4396437dSToby Isaac   PetscFunctionReturn(0);
799*4396437dSToby Isaac }
800*4396437dSToby Isaac 
801*4396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X)
802*4396437dSToby Isaac {
803*4396437dSToby Isaac   PetscScalar    *y;
804*4396437dSToby Isaac   PetscBLASInt   m, k, ylda, nrhs;
805*4396437dSToby Isaac   PetscErrorCode ierr;
806*4396437dSToby Isaac 
807*4396437dSToby Isaac   PetscFunctionBegin;
808*4396437dSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
809*4396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_QR(A, y, ylda, m, nrhs, k);CHKERRQ(ierr);
810*4396437dSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
811*4396437dSToby Isaac   PetscFunctionReturn(0);
812*4396437dSToby Isaac }
813*4396437dSToby Isaac 
814*4396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X)
815*4396437dSToby Isaac {
816*4396437dSToby Isaac   PetscScalar    *y;
817*4396437dSToby Isaac   PetscBLASInt   m, k, ylda, nrhs;
818*4396437dSToby Isaac   PetscErrorCode ierr;
819*4396437dSToby Isaac 
820*4396437dSToby Isaac   PetscFunctionBegin;
821*4396437dSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
822*4396437dSToby Isaac   ierr = MatSolveTranspose_SeqDense_Internal_QR(A, y, ylda, m, nrhs, k);CHKERRQ(ierr);
823*4396437dSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
824*4396437dSToby Isaac   PetscFunctionReturn(0);
825*4396437dSToby Isaac }
826*4396437dSToby Isaac 
82700121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
82800121966SStefano Zampini 
829db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
830db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
831db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
832ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
833db4efbfdSBarry Smith {
834db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
835db4efbfdSBarry Smith   PetscErrorCode ierr;
836db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
837db4efbfdSBarry Smith 
838db4efbfdSBarry Smith   PetscFunctionBegin;
839c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
840c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
841db4efbfdSBarry Smith   if (!mat->pivots) {
8428208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
8433bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
844db4efbfdSBarry Smith   }
845db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
8468e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
8478b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
8488e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
8498e57ea43SSatish Balay 
850e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
851e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
8528208b9aeSStefano Zampini 
853*4396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
854*4396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
855*4396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
856*4396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
857d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
858db4efbfdSBarry Smith 
859f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
860f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
861f6224b95SHong Zhang 
862dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
863db4efbfdSBarry Smith   PetscFunctionReturn(0);
864db4efbfdSBarry Smith }
865db4efbfdSBarry Smith 
866*4396437dSToby Isaac static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
867*4396437dSToby Isaac {
868*4396437dSToby Isaac   MatFactorInfo  info;
869*4396437dSToby Isaac   PetscErrorCode ierr;
870*4396437dSToby Isaac 
871*4396437dSToby Isaac   PetscFunctionBegin;
872*4396437dSToby Isaac   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
873*4396437dSToby Isaac   ierr = (*fact->ops->lufactor)(fact,NULL,NULL,&info);CHKERRQ(ierr);
874*4396437dSToby Isaac   PetscFunctionReturn(0);
875*4396437dSToby Isaac }
876*4396437dSToby Isaac 
877*4396437dSToby Isaac PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
878*4396437dSToby Isaac {
879*4396437dSToby Isaac   PetscFunctionBegin;
880*4396437dSToby Isaac   fact->preallocated           = PETSC_TRUE;
881*4396437dSToby Isaac   fact->assembled              = PETSC_TRUE;
882*4396437dSToby Isaac   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
883*4396437dSToby Isaac   fact->ops->solve             = MatSolve_SeqDense_LU;
884*4396437dSToby Isaac   fact->ops->matsolve          = MatMatSolve_SeqDense_LU;
885*4396437dSToby Isaac   fact->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
886*4396437dSToby Isaac   PetscFunctionReturn(0);
887*4396437dSToby Isaac }
888*4396437dSToby Isaac 
889a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
890ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
891db4efbfdSBarry Smith {
892db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
893db4efbfdSBarry Smith   PetscErrorCode ierr;
894c5df96a5SBarry Smith   PetscBLASInt   info,n;
895db4efbfdSBarry Smith 
896db4efbfdSBarry Smith   PetscFunctionBegin;
897c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
898db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
899a49dc2a2SStefano Zampini   if (A->spd) {
90000121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
9018b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
90200121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
903a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
904a49dc2a2SStefano Zampini   } else if (A->hermitian) {
905a49dc2a2SStefano Zampini     if (!mat->pivots) {
906a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
907a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
908a49dc2a2SStefano Zampini     }
909a49dc2a2SStefano Zampini     if (!mat->fwork) {
910a49dc2a2SStefano Zampini       PetscScalar dummy;
911a49dc2a2SStefano Zampini 
912a49dc2a2SStefano Zampini       mat->lfwork = -1;
91300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
914a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
91500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
916a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
917a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
918a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
919a49dc2a2SStefano Zampini     }
92000121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
921a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
92200121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
923a49dc2a2SStefano Zampini #endif
924a49dc2a2SStefano Zampini   } else { /* symmetric case */
925a49dc2a2SStefano Zampini     if (!mat->pivots) {
926a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
927a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
928a49dc2a2SStefano Zampini     }
929a49dc2a2SStefano Zampini     if (!mat->fwork) {
930a49dc2a2SStefano Zampini       PetscScalar dummy;
931a49dc2a2SStefano Zampini 
932a49dc2a2SStefano Zampini       mat->lfwork = -1;
93300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
934a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
93500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
936a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
937a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
938a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
939a49dc2a2SStefano Zampini     }
94000121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
941a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
94200121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
943a49dc2a2SStefano Zampini   }
944e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
9458208b9aeSStefano Zampini 
946*4396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
947*4396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
948*4396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
949*4396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
950d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
9512205254eSKarl Rupp 
952f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
953f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
954f6224b95SHong Zhang 
955eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
956db4efbfdSBarry Smith   PetscFunctionReturn(0);
957db4efbfdSBarry Smith }
958db4efbfdSBarry Smith 
959*4396437dSToby Isaac static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
960db4efbfdSBarry Smith {
961db4efbfdSBarry Smith   PetscErrorCode ierr;
962db4efbfdSBarry Smith   MatFactorInfo  info;
963db4efbfdSBarry Smith 
964db4efbfdSBarry Smith   PetscFunctionBegin;
965db4efbfdSBarry Smith   info.fill = 1.0;
9662205254eSKarl Rupp 
967c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
968f4259b30SLisandro Dalcin   ierr = (*fact->ops->choleskyfactor)(fact,NULL,&info);CHKERRQ(ierr);
969db4efbfdSBarry Smith   PetscFunctionReturn(0);
970db4efbfdSBarry Smith }
971db4efbfdSBarry Smith 
972ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
973db4efbfdSBarry Smith {
974db4efbfdSBarry Smith   PetscFunctionBegin;
975c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9761bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
977719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
978*4396437dSToby Isaac   fact->ops->solve                 = MatSolve_SeqDense_Cholesky;
979*4396437dSToby Isaac   fact->ops->matsolve              = MatMatSolve_SeqDense_Cholesky;
980*4396437dSToby Isaac   fact->ops->solvetranspose        = MatSolve_SeqDense_Cholesky;
981db4efbfdSBarry Smith   PetscFunctionReturn(0);
982db4efbfdSBarry Smith }
983db4efbfdSBarry Smith 
9844905a7bcSToby Isaac static PetscErrorCode MatQRFactor_SeqDense(Mat A,IS col,const MatFactorInfo *minfo)
9854905a7bcSToby Isaac {
9864905a7bcSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
9874905a7bcSToby Isaac   PetscErrorCode ierr;
9884905a7bcSToby Isaac   PetscBLASInt   n,m,info, min, max;
9894905a7bcSToby Isaac 
9904905a7bcSToby Isaac   PetscFunctionBegin;
9914905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
9924905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
993*4396437dSToby Isaac   max = PetscMax(m, n);
994*4396437dSToby Isaac   min = PetscMin(m, n);
9954905a7bcSToby Isaac   if (!mat->tau) {
996*4396437dSToby Isaac     ierr = PetscMalloc1(min,&mat->tau);CHKERRQ(ierr);
997*4396437dSToby Isaac     ierr = PetscLogObjectMemory((PetscObject)A,min*sizeof(PetscScalar));CHKERRQ(ierr);
998*4396437dSToby Isaac   }
999*4396437dSToby Isaac   if (!mat->pivots) {
1000*4396437dSToby Isaac     ierr = PetscMalloc1(m,&mat->pivots);CHKERRQ(ierr);
1001*4396437dSToby Isaac     ierr = PetscLogObjectMemory((PetscObject)A,m*sizeof(PetscScalar));CHKERRQ(ierr);
1002*4396437dSToby Isaac   }
1003*4396437dSToby Isaac   if (!mat->qrrhs) {
1004*4396437dSToby Isaac     ierr = MatCreateVecs(A, NULL, &(mat->qrrhs));CHKERRQ(ierr);
10054905a7bcSToby Isaac   }
10064905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
10074905a7bcSToby Isaac   if (!mat->fwork) {
10084905a7bcSToby Isaac     PetscScalar dummy;
10094905a7bcSToby Isaac 
10104905a7bcSToby Isaac     mat->lfwork = -1;
10114905a7bcSToby Isaac     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
10124905a7bcSToby Isaac     PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,&dummy,&mat->lfwork,&info));
10134905a7bcSToby Isaac     ierr = PetscFPTrapPop();CHKERRQ(ierr);
10144905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
10154905a7bcSToby Isaac     ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
10164905a7bcSToby Isaac     ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
10174905a7bcSToby Isaac   }
10184905a7bcSToby Isaac   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
10194905a7bcSToby Isaac   PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,mat->fwork,&mat->lfwork,&info));
10204905a7bcSToby Isaac   ierr = PetscFPTrapPop();CHKERRQ(ierr);
10214905a7bcSToby Isaac   if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to QR factorization");
10224905a7bcSToby 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
10234905a7bcSToby Isaac   mat->rank = min;
10244905a7bcSToby Isaac 
1025*4396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_QR;
1026*4396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_QR;
10274905a7bcSToby Isaac   A->factortype             = MAT_FACTOR_QR;
10284905a7bcSToby Isaac   if (m == n) {
1029*4396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
1030*4396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
10314905a7bcSToby Isaac   }
10324905a7bcSToby Isaac 
10334905a7bcSToby Isaac   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
10344905a7bcSToby Isaac   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
10354905a7bcSToby Isaac 
10364905a7bcSToby Isaac   ierr = PetscLogFlops(2.0*min*min*(max-min/3.0));CHKERRQ(ierr);
10374905a7bcSToby Isaac   PetscFunctionReturn(0);
10384905a7bcSToby Isaac }
10394905a7bcSToby Isaac 
10404905a7bcSToby Isaac static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
10414905a7bcSToby Isaac {
10424905a7bcSToby Isaac   PetscErrorCode ierr;
10434905a7bcSToby Isaac   MatFactorInfo  info;
10444905a7bcSToby Isaac 
10454905a7bcSToby Isaac   PetscFunctionBegin;
10464905a7bcSToby Isaac   info.fill = 1.0;
10474905a7bcSToby Isaac 
10484905a7bcSToby Isaac   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
10494905a7bcSToby Isaac   ierr = MatQRFactor_SeqDense(fact,NULL,&info);CHKERRQ(ierr);
10504905a7bcSToby Isaac   PetscFunctionReturn(0);
10514905a7bcSToby Isaac }
10524905a7bcSToby Isaac 
10534905a7bcSToby Isaac static PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
10544905a7bcSToby Isaac {
10554905a7bcSToby Isaac   PetscErrorCode ierr;
10564905a7bcSToby Isaac 
10574905a7bcSToby Isaac   PetscFunctionBegin;
10584905a7bcSToby Isaac   fact->assembled                  = PETSC_TRUE;
10594905a7bcSToby Isaac   fact->preallocated               = PETSC_TRUE;
1060*4396437dSToby Isaac   fact->ops->solve                 = MatSolve_SeqDense_QR;
1061*4396437dSToby Isaac   fact->ops->matsolve              = MatMatSolve_SeqDense_QR;
1062*4396437dSToby Isaac   if (A->cmap->n == A->rmap->n) {
1063*4396437dSToby Isaac     fact->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
1064*4396437dSToby Isaac     fact->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
1065*4396437dSToby Isaac   }
10664905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)fact,"MatQRFactorNumeric_C",MatQRFactorNumeric_SeqDense);CHKERRQ(ierr);
10674905a7bcSToby Isaac   PetscFunctionReturn(0);
10684905a7bcSToby Isaac }
10694905a7bcSToby Isaac 
10704905a7bcSToby Isaac 
1071ca15aa20SStefano Zampini /* uses LAPACK */
1072cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
1073db4efbfdSBarry Smith {
1074db4efbfdSBarry Smith   PetscErrorCode ierr;
1075db4efbfdSBarry Smith 
1076db4efbfdSBarry Smith   PetscFunctionBegin;
1077ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
1078db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1079ca15aa20SStefano Zampini   ierr = MatSetType(*fact,MATDENSE);CHKERRQ(ierr);
10802a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
1081db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
10822a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
1083db4efbfdSBarry Smith   } else {
1084db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
1085db4efbfdSBarry Smith   }
1086d5f3da31SBarry Smith   (*fact)->factortype = ftype;
108700c67f3bSHong Zhang 
108800c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
108900c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
1090db4efbfdSBarry Smith   PetscFunctionReturn(0);
1091db4efbfdSBarry Smith }
1092db4efbfdSBarry Smith 
1093289bc588SBarry Smith /* ------------------------------------------------------------------*/
1094e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
1095289bc588SBarry Smith {
1096c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1097d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
1098d9ca1df4SBarry Smith   const PetscScalar *b;
1099dfbe8321SBarry Smith   PetscErrorCode    ierr;
1100d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
110123fff9afSBarry Smith   PetscBLASInt      o = 1,bm = 0;
1102289bc588SBarry Smith 
11033a40ed3dSBarry Smith   PetscFunctionBegin;
1104ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1105c70f7ee4SJunchao Zhang   if (A->offloadmask == PETSC_OFFLOAD_GPU) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
1106ca15aa20SStefano Zampini #endif
1107422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
1108c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
1109289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
11103bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
11112dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
1112289bc588SBarry Smith   }
11131ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1114d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1115b965ef7fSBarry Smith   its  = its*lits;
1116e32f2f54SBarry 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);
1117289bc588SBarry Smith   while (its--) {
1118fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1119289bc588SBarry Smith       for (i=0; i<m; i++) {
11203bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
112155a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1122289bc588SBarry Smith       }
1123289bc588SBarry Smith     }
1124fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1125289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
11263bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
112755a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1128289bc588SBarry Smith       }
1129289bc588SBarry Smith     }
1130289bc588SBarry Smith   }
1131d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
11321ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11333a40ed3dSBarry Smith   PetscFunctionReturn(0);
1134289bc588SBarry Smith }
1135289bc588SBarry Smith 
1136289bc588SBarry Smith /* -----------------------------------------------------------------*/
1137ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
1138289bc588SBarry Smith {
1139c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1140d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
1141d9ca1df4SBarry Smith   PetscScalar       *y;
1142dfbe8321SBarry Smith   PetscErrorCode    ierr;
11430805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
1144ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
11453a40ed3dSBarry Smith 
11463a40ed3dSBarry Smith   PetscFunctionBegin;
1147c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1148c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
1149d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11502bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
11515ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11525ac36cfcSBarry Smith     PetscBLASInt i;
11535ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
11545ac36cfcSBarry Smith   } else {
11558b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
11565ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
11575ac36cfcSBarry Smith   }
1158d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
11592bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
11603a40ed3dSBarry Smith   PetscFunctionReturn(0);
1161289bc588SBarry Smith }
1162800995b7SMatthew Knepley 
1163ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
1164289bc588SBarry Smith {
1165c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1166d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
1167dfbe8321SBarry Smith   PetscErrorCode    ierr;
11680805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
1169d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
11703a40ed3dSBarry Smith 
11713a40ed3dSBarry Smith   PetscFunctionBegin;
1172c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1173c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
1174d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11752bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
11765ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11775ac36cfcSBarry Smith     PetscBLASInt i;
11785ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
11795ac36cfcSBarry Smith   } else {
11808b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
11815ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
11825ac36cfcSBarry Smith   }
1183d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
11842bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
11853a40ed3dSBarry Smith   PetscFunctionReturn(0);
1186289bc588SBarry Smith }
11876ee01492SSatish Balay 
1188ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1189289bc588SBarry Smith {
1190c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1191d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1192d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
1193dfbe8321SBarry Smith   PetscErrorCode    ierr;
11940805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
11953a40ed3dSBarry Smith 
11963a40ed3dSBarry Smith   PetscFunctionBegin;
1197c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1198c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
119917b127eeSStefano Zampini   ierr = VecCopy(zz,yy);CHKERRQ(ierr);
1200d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
1201d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12021ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
12038b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
1204d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12051ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1206dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
12073a40ed3dSBarry Smith   PetscFunctionReturn(0);
1208289bc588SBarry Smith }
12096ee01492SSatish Balay 
1210ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1211289bc588SBarry Smith {
1212c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1213d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1214d9ca1df4SBarry Smith   PetscScalar       *y;
1215dfbe8321SBarry Smith   PetscErrorCode    ierr;
12160805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
121787828ca2SBarry Smith   PetscScalar       _DOne=1.0;
12183a40ed3dSBarry Smith 
12193a40ed3dSBarry Smith   PetscFunctionBegin;
1220c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1221c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
122217b127eeSStefano Zampini   ierr = VecCopy(zz,yy);CHKERRQ(ierr);
1223d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
1224d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12251ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
12268b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
1227d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12281ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1229dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
12303a40ed3dSBarry Smith   PetscFunctionReturn(0);
1231289bc588SBarry Smith }
1232289bc588SBarry Smith 
1233289bc588SBarry Smith /* -----------------------------------------------------------------*/
1234e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1235289bc588SBarry Smith {
1236c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
12376849ba73SBarry Smith   PetscErrorCode ierr;
123813f74950SBarry Smith   PetscInt       i;
123967e560aaSBarry Smith 
12403a40ed3dSBarry Smith   PetscFunctionBegin;
1241d0f46423SBarry Smith   *ncols = A->cmap->n;
1242289bc588SBarry Smith   if (cols) {
1243854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
1244d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
1245289bc588SBarry Smith   }
1246289bc588SBarry Smith   if (vals) {
1247ca15aa20SStefano Zampini     const PetscScalar *v;
1248ca15aa20SStefano Zampini 
1249ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1250854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
1251ca15aa20SStefano Zampini     v   += row;
1252d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
1253ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1254289bc588SBarry Smith   }
12553a40ed3dSBarry Smith   PetscFunctionReturn(0);
1256289bc588SBarry Smith }
12576ee01492SSatish Balay 
1258e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1259289bc588SBarry Smith {
1260dfbe8321SBarry Smith   PetscErrorCode ierr;
12616e111a19SKarl Rupp 
1262606d414cSSatish Balay   PetscFunctionBegin;
1263606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
1264606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
12653a40ed3dSBarry Smith   PetscFunctionReturn(0);
1266289bc588SBarry Smith }
1267289bc588SBarry Smith /* ----------------------------------------------------------------*/
1268e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
1269289bc588SBarry Smith {
1270c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
1271ca15aa20SStefano Zampini   PetscScalar      *av;
127213f74950SBarry Smith   PetscInt         i,j,idx=0;
1273ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1274c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1275ca15aa20SStefano Zampini #endif
1276ca15aa20SStefano Zampini   PetscErrorCode   ierr;
1277d6dfbf8fSBarry Smith 
12783a40ed3dSBarry Smith   PetscFunctionBegin;
1279ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&av);CHKERRQ(ierr);
1280289bc588SBarry Smith   if (!mat->roworiented) {
1281dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1282289bc588SBarry Smith       for (j=0; j<n; j++) {
1283cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
1284cf9c20a2SJed 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);
1285289bc588SBarry Smith         for (i=0; i<m; i++) {
1286cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
1287cf9c20a2SJed 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);
1288ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1289289bc588SBarry Smith         }
1290289bc588SBarry Smith       }
12913a40ed3dSBarry Smith     } else {
1292289bc588SBarry Smith       for (j=0; j<n; j++) {
1293cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
1294cf9c20a2SJed 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);
1295289bc588SBarry Smith         for (i=0; i<m; i++) {
1296cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
1297cf9c20a2SJed 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);
1298ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1299289bc588SBarry Smith         }
1300289bc588SBarry Smith       }
1301289bc588SBarry Smith     }
13023a40ed3dSBarry Smith   } else {
1303dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1304e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
1305cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
1306cf9c20a2SJed 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);
1307e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
1308cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
1309cf9c20a2SJed 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);
1310ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1311e8d4e0b9SBarry Smith         }
1312e8d4e0b9SBarry Smith       }
13133a40ed3dSBarry Smith     } else {
1314289bc588SBarry Smith       for (i=0; i<m; i++) {
1315cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
1316cf9c20a2SJed 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);
1317289bc588SBarry Smith         for (j=0; j<n; j++) {
1318cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
1319cf9c20a2SJed 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);
1320ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1321289bc588SBarry Smith         }
1322289bc588SBarry Smith       }
1323289bc588SBarry Smith     }
1324e8d4e0b9SBarry Smith   }
1325ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
1326ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1327c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
1328c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1329ca15aa20SStefano Zampini #endif
1330ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&av);CHKERRQ(ierr);
1331ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1332c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1333ca15aa20SStefano Zampini #endif
13343a40ed3dSBarry Smith   PetscFunctionReturn(0);
1335289bc588SBarry Smith }
1336e8d4e0b9SBarry Smith 
1337e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1338ae80bb75SLois Curfman McInnes {
1339ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1340ca15aa20SStefano Zampini   const PetscScalar *vv;
134113f74950SBarry Smith   PetscInt          i,j;
1342ca15aa20SStefano Zampini   PetscErrorCode    ierr;
1343ae80bb75SLois Curfman McInnes 
13443a40ed3dSBarry Smith   PetscFunctionBegin;
1345ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1346ae80bb75SLois Curfman McInnes   /* row-oriented output */
1347ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
134897e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1349e32f2f54SBarry 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);
1350ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
13516f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1352e32f2f54SBarry 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);
1353ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1354ae80bb75SLois Curfman McInnes     }
1355ae80bb75SLois Curfman McInnes   }
1356ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
13573a40ed3dSBarry Smith   PetscFunctionReturn(0);
1358ae80bb75SLois Curfman McInnes }
1359ae80bb75SLois Curfman McInnes 
1360289bc588SBarry Smith /* -----------------------------------------------------------------*/
1361289bc588SBarry Smith 
13628491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1363aabbc4fbSShri Abhyankar {
1364aabbc4fbSShri Abhyankar   PetscErrorCode    ierr;
13658491ab44SLisandro Dalcin   PetscBool         skipHeader;
13668491ab44SLisandro Dalcin   PetscViewerFormat format;
13678491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
13688491ab44SLisandro Dalcin   const PetscScalar *v;
13698491ab44SLisandro Dalcin   PetscScalar       *vwork;
1370aabbc4fbSShri Abhyankar 
1371aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13728491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
13738491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
13748491ab44SLisandro Dalcin   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
13758491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1376aabbc4fbSShri Abhyankar 
13778491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
13788491ab44SLisandro Dalcin 
13798491ab44SLisandro Dalcin   /* write matrix header */
13808491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
13818491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
13828491ab44SLisandro Dalcin   if (!skipHeader) {ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);}
13838491ab44SLisandro Dalcin 
13848491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
13858491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13868491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
13878491ab44SLisandro Dalcin     /* store row lengths for each row */
13888491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
13898491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
13908491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
13918491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13928491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
13938491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
13948491ab44SLisandro Dalcin         iwork[k] = j;
13958491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
13968491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
13978491ab44SLisandro Dalcin   }
13988491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13998491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
14008491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
14018491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
14028491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
14038491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
14048491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
14058491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
14068491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
14078491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
14088491ab44SLisandro Dalcin   PetscFunctionReturn(0);
14098491ab44SLisandro Dalcin }
14108491ab44SLisandro Dalcin 
14118491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
14128491ab44SLisandro Dalcin {
14138491ab44SLisandro Dalcin   PetscErrorCode ierr;
14148491ab44SLisandro Dalcin   PetscBool      skipHeader;
14158491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
14168491ab44SLisandro Dalcin   PetscInt       rows,cols;
14178491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
14188491ab44SLisandro Dalcin 
14198491ab44SLisandro Dalcin   PetscFunctionBegin;
14208491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
14218491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
14228491ab44SLisandro Dalcin 
14238491ab44SLisandro Dalcin   if (!skipHeader) {
14248491ab44SLisandro Dalcin     ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
14258491ab44SLisandro Dalcin     if (header[0] != MAT_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
14268491ab44SLisandro Dalcin     M = header[1]; N = header[2];
14278491ab44SLisandro Dalcin     if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M);
14288491ab44SLisandro Dalcin     if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N);
14298491ab44SLisandro Dalcin     nz = header[3];
14308491ab44SLisandro Dalcin     if (nz != MATRIX_BINARY_FORMAT_DENSE && nz < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %D in file",nz);
1431aabbc4fbSShri Abhyankar   } else {
14328491ab44SLisandro Dalcin     ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
14338491ab44SLisandro 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");
14348491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1435e6324fbbSBarry Smith   }
1436aabbc4fbSShri Abhyankar 
14378491ab44SLisandro Dalcin   /* setup global sizes if not set */
14388491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
14398491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
14408491ab44SLisandro Dalcin   ierr = MatSetUp(mat);CHKERRQ(ierr);
14418491ab44SLisandro Dalcin   /* check if global sizes are correct */
14428491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
14438491ab44SLisandro 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);
1444aabbc4fbSShri Abhyankar 
14458491ab44SLisandro Dalcin   ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
14468491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
14478491ab44SLisandro Dalcin   ierr = MatDenseGetArray(mat,&v);CHKERRQ(ierr);
14488491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
14498491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
14508491ab44SLisandro Dalcin     PetscInt nnz = m*N;
14518491ab44SLisandro Dalcin     /* read in matrix values */
14528491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&vwork);CHKERRQ(ierr);
14538491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
14548491ab44SLisandro Dalcin     /* store values in column major order */
14558491ab44SLisandro Dalcin     for (j=0; j<N; j++)
14568491ab44SLisandro Dalcin       for (i=0; i<m; i++)
14578491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
14588491ab44SLisandro Dalcin     ierr = PetscFree(vwork);CHKERRQ(ierr);
14598491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14608491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14618491ab44SLisandro Dalcin     /* read in row lengths */
14628491ab44SLisandro Dalcin     ierr = PetscMalloc1(m,&rlens);CHKERRQ(ierr);
14638491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
14648491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
14658491ab44SLisandro Dalcin     /* read in column indices and values */
14668491ab44SLisandro Dalcin     ierr = PetscMalloc2(nnz,&icols,nnz,&vwork);CHKERRQ(ierr);
14678491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
14688491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
14698491ab44SLisandro Dalcin     /* store values in column major order */
14708491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
14718491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
14728491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
14738491ab44SLisandro Dalcin     ierr = PetscFree(rlens);CHKERRQ(ierr);
14748491ab44SLisandro Dalcin     ierr = PetscFree2(icols,vwork);CHKERRQ(ierr);
1475aabbc4fbSShri Abhyankar   }
14768491ab44SLisandro Dalcin   ierr = MatDenseRestoreArray(mat,&v);CHKERRQ(ierr);
14778491ab44SLisandro Dalcin   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14788491ab44SLisandro Dalcin   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1479aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1480aabbc4fbSShri Abhyankar }
1481aabbc4fbSShri Abhyankar 
1482eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1483eb91f321SVaclav Hapla {
1484eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1485eb91f321SVaclav Hapla   PetscErrorCode ierr;
1486eb91f321SVaclav Hapla 
1487eb91f321SVaclav Hapla   PetscFunctionBegin;
1488eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1489eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1490eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
1491eb91f321SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1492eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1493eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1494eb91f321SVaclav Hapla   if (isbinary) {
14958491ab44SLisandro Dalcin     ierr = MatLoad_Dense_Binary(newMat,viewer);CHKERRQ(ierr);
1496eb91f321SVaclav Hapla   } else if (ishdf5) {
1497eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
1498eb91f321SVaclav Hapla     ierr = MatLoad_Dense_HDF5(newMat,viewer);CHKERRQ(ierr);
1499eb91f321SVaclav Hapla #else
1500eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1501eb91f321SVaclav Hapla #endif
1502eb91f321SVaclav Hapla   } else {
1503eb91f321SVaclav 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);
1504eb91f321SVaclav Hapla   }
1505eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1506eb91f321SVaclav Hapla }
1507eb91f321SVaclav Hapla 
15086849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1509289bc588SBarry Smith {
1510932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1511dfbe8321SBarry Smith   PetscErrorCode    ierr;
151213f74950SBarry Smith   PetscInt          i,j;
15132dcb1b2aSMatthew Knepley   const char        *name;
1514ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1515f3ef73ceSBarry Smith   PetscViewerFormat format;
15165f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1517ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
15185f481a85SSatish Balay #endif
1519932b0c3eSLois Curfman McInnes 
15203a40ed3dSBarry Smith   PetscFunctionBegin;
1521ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1522b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1523456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
15243a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1525fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1526d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1527d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1528ca15aa20SStefano Zampini       v    = av + i;
152977431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1530d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1531aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1532329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
153357622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1534329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
153557622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
15366831982aSBarry Smith         }
153780cd9d93SLois Curfman McInnes #else
15386831982aSBarry Smith         if (*v) {
153957622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
15406831982aSBarry Smith         }
154180cd9d93SLois Curfman McInnes #endif
15421b807ce4Svictorle         v += a->lda;
154380cd9d93SLois Curfman McInnes       }
1544b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
154580cd9d93SLois Curfman McInnes     }
1546d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
15473a40ed3dSBarry Smith   } else {
1548d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1549aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
155047989497SBarry Smith     /* determine if matrix has all real values */
1551ca15aa20SStefano Zampini     v = av;
1552d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1553ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
155447989497SBarry Smith     }
155547989497SBarry Smith #endif
1556fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15573a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1558d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1559d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1560fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1561ffac6cdbSBarry Smith     }
1562ffac6cdbSBarry Smith 
1563d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1564ca15aa20SStefano Zampini       v = av + i;
1565d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1566aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
156747989497SBarry Smith         if (allreal) {
1568c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
156947989497SBarry Smith         } else {
1570c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
157147989497SBarry Smith         }
1572289bc588SBarry Smith #else
1573c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1574289bc588SBarry Smith #endif
15751b807ce4Svictorle         v += a->lda;
1576289bc588SBarry Smith       }
1577b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1578289bc588SBarry Smith     }
1579fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1580b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1581ffac6cdbSBarry Smith     }
1582d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1583da3a660dSBarry Smith   }
1584ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1585b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
15863a40ed3dSBarry Smith   PetscFunctionReturn(0);
1587289bc588SBarry Smith }
1588289bc588SBarry Smith 
15899804daf3SBarry Smith #include <petscdraw.h>
1590e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1591f1af5d2fSBarry Smith {
1592f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
15936849ba73SBarry Smith   PetscErrorCode    ierr;
1594383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1595383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1596ca15aa20SStefano Zampini   const PetscScalar *v;
1597b0a32e0cSBarry Smith   PetscViewer       viewer;
1598b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1599f3ef73ceSBarry Smith   PetscViewerFormat format;
1600f1af5d2fSBarry Smith 
1601f1af5d2fSBarry Smith   PetscFunctionBegin;
1602f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1603b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1604b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1605f1af5d2fSBarry Smith 
1606f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1607ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1608fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1609383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1610f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1611f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1612383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1613f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1614f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1615f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1616ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1617ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1618ca15aa20SStefano Zampini         else continue;
1619b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1620f1af5d2fSBarry Smith       }
1621f1af5d2fSBarry Smith     }
1622383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1623f1af5d2fSBarry Smith   } else {
1624f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1625f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1626b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1627b05fc000SLisandro Dalcin     PetscDraw popup;
1628b05fc000SLisandro Dalcin 
1629f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1630f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1631f1af5d2fSBarry Smith     }
1632383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1633b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
163445f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1635383922c3SLisandro Dalcin 
1636383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1637f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1638f1af5d2fSBarry Smith       x_l = j;
1639f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1640f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1641f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1642f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1643b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1644b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1645f1af5d2fSBarry Smith       }
1646f1af5d2fSBarry Smith     }
1647383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1648f1af5d2fSBarry Smith   }
1649ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1650f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1651f1af5d2fSBarry Smith }
1652f1af5d2fSBarry Smith 
1653e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1654f1af5d2fSBarry Smith {
1655b0a32e0cSBarry Smith   PetscDraw      draw;
1656ace3abfcSBarry Smith   PetscBool      isnull;
1657329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1658dfbe8321SBarry Smith   PetscErrorCode ierr;
1659f1af5d2fSBarry Smith 
1660f1af5d2fSBarry Smith   PetscFunctionBegin;
1661b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1662b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1663abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1664f1af5d2fSBarry Smith 
1665d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1666f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1667b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1668832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1669b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
16700298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1671832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1672f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1673f1af5d2fSBarry Smith }
1674f1af5d2fSBarry Smith 
1675dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1676932b0c3eSLois Curfman McInnes {
1677dfbe8321SBarry Smith   PetscErrorCode ierr;
1678ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1679932b0c3eSLois Curfman McInnes 
16803a40ed3dSBarry Smith   PetscFunctionBegin;
1681251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1682251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1683251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
16840f5bd95cSBarry Smith 
1685c45a1595SBarry Smith   if (iascii) {
1686c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
16870f5bd95cSBarry Smith   } else if (isbinary) {
1688637a0070SStefano Zampini     ierr = MatView_Dense_Binary(A,viewer);CHKERRQ(ierr);
1689f1af5d2fSBarry Smith   } else if (isdraw) {
1690f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1691932b0c3eSLois Curfman McInnes   }
16923a40ed3dSBarry Smith   PetscFunctionReturn(0);
1693932b0c3eSLois Curfman McInnes }
1694289bc588SBarry Smith 
1695637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array)
1696d3042a70SBarry Smith {
1697d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1698d3042a70SBarry Smith 
1699d3042a70SBarry Smith   PetscFunctionBegin;
17005ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
17015ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
17025ea7661aSPierre Jolivet   if (a->unplacedarray) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreArray() first");
1703d3042a70SBarry Smith   a->unplacedarray       = a->v;
1704d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1705d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1706637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1707ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1708c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1709ca15aa20SStefano Zampini #endif
1710d3042a70SBarry Smith   PetscFunctionReturn(0);
1711d3042a70SBarry Smith }
1712d3042a70SBarry Smith 
1713d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1714d3042a70SBarry Smith {
1715d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1716d3042a70SBarry Smith 
1717d3042a70SBarry Smith   PetscFunctionBegin;
17185ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
17195ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1720d3042a70SBarry Smith   a->v             = a->unplacedarray;
1721d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1722d3042a70SBarry Smith   a->unplacedarray = NULL;
1723ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1724c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1725ca15aa20SStefano Zampini #endif
1726d3042a70SBarry Smith   PetscFunctionReturn(0);
1727d3042a70SBarry Smith }
1728d3042a70SBarry Smith 
1729d5ea218eSStefano Zampini static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A,const PetscScalar *array)
1730d5ea218eSStefano Zampini {
1731d5ea218eSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1732d5ea218eSStefano Zampini   PetscErrorCode ierr;
1733d5ea218eSStefano Zampini 
1734d5ea218eSStefano Zampini   PetscFunctionBegin;
17355ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
17365ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1737d5ea218eSStefano Zampini   if (!a->user_alloc) { ierr = PetscFree(a->v);CHKERRQ(ierr); }
1738d5ea218eSStefano Zampini   a->v           = (PetscScalar*) array;
1739d5ea218eSStefano Zampini   a->user_alloc  = PETSC_FALSE;
1740d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1741d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1742d5ea218eSStefano Zampini #endif
1743d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1744d5ea218eSStefano Zampini }
1745d5ea218eSStefano Zampini 
1746ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1747289bc588SBarry Smith {
1748ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1749dfbe8321SBarry Smith   PetscErrorCode ierr;
175090f02eecSBarry Smith 
17513a40ed3dSBarry Smith   PetscFunctionBegin;
1752aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1753d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1754a5a9c739SBarry Smith #endif
1755*4396437dSToby Isaac   ierr = VecDestroy(&(l->qrrhs));CHKERRQ(ierr);
17564905a7bcSToby Isaac   ierr = PetscFree(l->tau);CHKERRQ(ierr);
175705b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1758a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1759abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
17606857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1761637a0070SStefano Zampini   if (!l->unplaced_user_alloc) {ierr = PetscFree(l->unplacedarray);CHKERRQ(ierr);}
17625ea7661aSPierre Jolivet   if (l->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
17635ea7661aSPierre Jolivet   if (l->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
17646947451fSStefano Zampini   ierr = VecDestroy(&l->cvec);CHKERRQ(ierr);
17655ea7661aSPierre Jolivet   ierr = MatDestroy(&l->cmat);CHKERRQ(ierr);
1766bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1767dbd8c25aSHong Zhang 
1768f4259b30SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)mat,NULL);CHKERRQ(ierr);
17694905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatQRFactor_C",NULL);CHKERRQ(ierr);
17704905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatQRFactorNumeric_C",NULL);CHKERRQ(ierr);
17714905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatQRFactorSymbolic_C",NULL);CHKERRQ(ierr);
177249a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1773ad16ce7aSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseSetLDA_C",NULL);CHKERRQ(ierr);
1774bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
177552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
1776d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1777d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
1778d5ea218eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseReplaceArray_C",NULL);CHKERRQ(ierr);
177952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL);CHKERRQ(ierr);
178052c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL);CHKERRQ(ierr);
17816947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayWrite_C",NULL);CHKERRQ(ierr);
17826947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayWrite_C",NULL);CHKERRQ(ierr);
17838baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
17848baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17858baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
17868baccfbdSHong Zhang #endif
1787d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
1788d24d4204SJose E. Roman   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_scalapack_C",NULL);CHKERRQ(ierr);
1789d24d4204SJose E. Roman #endif
17902bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17912bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL);CHKERRQ(ierr);
17924222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL);CHKERRQ(ierr);
17934222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL);CHKERRQ(ierr);
17942bf066beSStefano Zampini #endif
1795bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
17964222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
17974222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL);CHKERRQ(ierr);
17984222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
17994222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
180052c5f739Sprj- 
180186aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
180286aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
18036947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVec_C",NULL);CHKERRQ(ierr);
18046947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVec_C",NULL);CHKERRQ(ierr);
18056947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecRead_C",NULL);CHKERRQ(ierr);
18066947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecRead_C",NULL);CHKERRQ(ierr);
18076947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecWrite_C",NULL);CHKERRQ(ierr);
18086947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecWrite_C",NULL);CHKERRQ(ierr);
18095ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetSubMatrix_C",NULL);CHKERRQ(ierr);
18105ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreSubMatrix_C",NULL);CHKERRQ(ierr);
18113a40ed3dSBarry Smith   PetscFunctionReturn(0);
1812289bc588SBarry Smith }
1813289bc588SBarry Smith 
1814e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1815289bc588SBarry Smith {
1816c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
18176849ba73SBarry Smith   PetscErrorCode ierr;
18186536e3caSStefano Zampini   PetscInt       k,j,m = A->rmap->n, M = mat->lda, n = A->cmap->n;
181987828ca2SBarry Smith   PetscScalar    *v,tmp;
182048b35521SBarry Smith 
18213a40ed3dSBarry Smith   PetscFunctionBegin;
18226536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
18236536e3caSStefano Zampini     if (m == n) { /* in place transpose */
1824ca15aa20SStefano Zampini       ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1825d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1826289bc588SBarry Smith         for (k=0; k<j; k++) {
18271b807ce4Svictorle           tmp        = v[j + k*M];
18281b807ce4Svictorle           v[j + k*M] = v[k + j*M];
18291b807ce4Svictorle           v[k + j*M] = tmp;
1830289bc588SBarry Smith         }
1831289bc588SBarry Smith       }
1832ca15aa20SStefano Zampini       ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
18336536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
18346536e3caSStefano Zampini       PetscScalar *v2;
18356536e3caSStefano Zampini       PetscLayout tmplayout;
18366536e3caSStefano Zampini 
18376536e3caSStefano Zampini       ierr = PetscMalloc1((size_t)m*n,&v2);CHKERRQ(ierr);
18386536e3caSStefano Zampini       ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
18396536e3caSStefano Zampini       for (j=0; j<n; j++) {
18406536e3caSStefano Zampini         for (k=0; k<m; k++) v2[j + (size_t)k*n] = v[k + (size_t)j*M];
18416536e3caSStefano Zampini       }
18426536e3caSStefano Zampini       ierr = PetscArraycpy(v,v2,(size_t)m*n);CHKERRQ(ierr);
18436536e3caSStefano Zampini       ierr = PetscFree(v2);CHKERRQ(ierr);
18446536e3caSStefano Zampini       ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
18456536e3caSStefano Zampini       /* cleanup size dependent quantities */
18466536e3caSStefano Zampini       ierr = VecDestroy(&mat->cvec);CHKERRQ(ierr);
18476536e3caSStefano Zampini       ierr = MatDestroy(&mat->cmat);CHKERRQ(ierr);
18486536e3caSStefano Zampini       ierr = PetscFree(mat->pivots);CHKERRQ(ierr);
18496536e3caSStefano Zampini       ierr = PetscFree(mat->fwork);CHKERRQ(ierr);
18506536e3caSStefano Zampini       ierr = MatDestroy(&mat->ptapwork);CHKERRQ(ierr);
18516536e3caSStefano Zampini       /* swap row/col layouts */
18526536e3caSStefano Zampini       mat->lda  = n;
18536536e3caSStefano Zampini       tmplayout = A->rmap;
18546536e3caSStefano Zampini       A->rmap   = A->cmap;
18556536e3caSStefano Zampini       A->cmap   = tmplayout;
18566536e3caSStefano Zampini     }
18573a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1858d3e5ee88SLois Curfman McInnes     Mat          tmat;
1859ec8511deSBarry Smith     Mat_SeqDense *tmatd;
186087828ca2SBarry Smith     PetscScalar  *v2;
1861af36a384SStefano Zampini     PetscInt     M2;
1862ea709b57SSatish Balay 
18636536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
1864ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1865d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
18667adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
18670298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1868ca15aa20SStefano Zampini     } else tmat = *matout;
1869ca15aa20SStefano Zampini 
1870ca15aa20SStefano Zampini     ierr  = MatDenseGetArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
1871ca15aa20SStefano Zampini     ierr  = MatDenseGetArray(tmat,&v2);CHKERRQ(ierr);
1872ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1873ca15aa20SStefano Zampini     M2    = tmatd->lda;
1874d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1875af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1876d3e5ee88SLois Curfman McInnes     }
1877ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(tmat,&v2);CHKERRQ(ierr);
1878ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
18796d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18806d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18816536e3caSStefano Zampini     *matout = tmat;
188248b35521SBarry Smith   }
18833a40ed3dSBarry Smith   PetscFunctionReturn(0);
1884289bc588SBarry Smith }
1885289bc588SBarry Smith 
1886e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1887289bc588SBarry Smith {
1888c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1889c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1890ca15aa20SStefano Zampini   PetscInt          i;
1891ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
1892ca15aa20SStefano Zampini   PetscErrorCode    ierr;
18939ea5d5aeSSatish Balay 
18943a40ed3dSBarry Smith   PetscFunctionBegin;
1895d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1896d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1897ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A1,&v1);CHKERRQ(ierr);
1898ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A2,&v2);CHKERRQ(ierr);
1899ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
1900ca15aa20SStefano Zampini     ierr = PetscArraycmp(v1,v2,A1->rmap->n,flg);CHKERRQ(ierr);
1901ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1902ca15aa20SStefano Zampini     v1 += mat1->lda;
1903ca15aa20SStefano Zampini     v2 += mat2->lda;
19041b807ce4Svictorle   }
1905ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A1,&v1);CHKERRQ(ierr);
1906ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A2,&v2);CHKERRQ(ierr);
190777c4ece6SBarry Smith   *flg = PETSC_TRUE;
19083a40ed3dSBarry Smith   PetscFunctionReturn(0);
1909289bc588SBarry Smith }
1910289bc588SBarry Smith 
1911e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1912289bc588SBarry Smith {
1913c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
191413f74950SBarry Smith   PetscInt          i,n,len;
1915ca15aa20SStefano Zampini   PetscScalar       *x;
1916ca15aa20SStefano Zampini   const PetscScalar *vv;
1917ca15aa20SStefano Zampini   PetscErrorCode    ierr;
191844cd7ae7SLois Curfman McInnes 
19193a40ed3dSBarry Smith   PetscFunctionBegin;
19207a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
19211ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1922d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1923ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1924e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
192544cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1926ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1927289bc588SBarry Smith   }
1928ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
19291ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
19303a40ed3dSBarry Smith   PetscFunctionReturn(0);
1931289bc588SBarry Smith }
1932289bc588SBarry Smith 
1933e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1934289bc588SBarry Smith {
1935c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1936f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1937ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1938dfbe8321SBarry Smith   PetscErrorCode    ierr;
1939d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
194055659b69SBarry Smith 
19413a40ed3dSBarry Smith   PetscFunctionBegin;
1942ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&vv);CHKERRQ(ierr);
194328988994SBarry Smith   if (ll) {
19447a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1945f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1946e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1947da3a660dSBarry Smith     for (i=0; i<m; i++) {
1948da3a660dSBarry Smith       x = l[i];
1949ca15aa20SStefano Zampini       v = vv + i;
1950b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1951da3a660dSBarry Smith     }
1952f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1953eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1954da3a660dSBarry Smith   }
195528988994SBarry Smith   if (rr) {
19567a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1957f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1958e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1959da3a660dSBarry Smith     for (i=0; i<n; i++) {
1960da3a660dSBarry Smith       x = r[i];
1961ca15aa20SStefano Zampini       v = vv + i*mat->lda;
19622205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1963da3a660dSBarry Smith     }
1964f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1965eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1966da3a660dSBarry Smith   }
1967ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&vv);CHKERRQ(ierr);
19683a40ed3dSBarry Smith   PetscFunctionReturn(0);
1969289bc588SBarry Smith }
1970289bc588SBarry Smith 
1971ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1972289bc588SBarry Smith {
1973c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1974ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1975329f5518SBarry Smith   PetscReal         sum  = 0.0;
1976d0f46423SBarry Smith   PetscInt          lda  =mat->lda,m=A->rmap->n,i,j;
1977efee365bSSatish Balay   PetscErrorCode    ierr;
197855659b69SBarry Smith 
19793a40ed3dSBarry Smith   PetscFunctionBegin;
1980ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
1981ca15aa20SStefano Zampini   v    = vv;
1982289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1983a5ce6ee0Svictorle     if (lda>m) {
1984d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1985ca15aa20SStefano Zampini         v = vv+j*lda;
1986a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1987a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1988a5ce6ee0Svictorle         }
1989a5ce6ee0Svictorle       }
1990a5ce6ee0Svictorle     } else {
1991570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1992570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
199373cf7048SBarry Smith       PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&cnt,v,&one));
1994570b7f6dSBarry Smith     }
1995570b7f6dSBarry Smith #else
1996d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1997329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1998289bc588SBarry Smith       }
1999a5ce6ee0Svictorle     }
20008f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
2001570b7f6dSBarry Smith #endif
2002dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
20033a40ed3dSBarry Smith   } else if (type == NORM_1) {
2004064f8208SBarry Smith     *nrm = 0.0;
2005d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2006ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
2007289bc588SBarry Smith       sum = 0.0;
2008d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
200933a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
2010289bc588SBarry Smith       }
2011064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
2012289bc588SBarry Smith     }
2013eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
20143a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2015064f8208SBarry Smith     *nrm = 0.0;
2016d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
2017ca15aa20SStefano Zampini       v   = vv + j;
2018289bc588SBarry Smith       sum = 0.0;
2019d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
20201b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
2021289bc588SBarry Smith       }
2022064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
2023289bc588SBarry Smith     }
2024eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
2025e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
2026ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
20273a40ed3dSBarry Smith   PetscFunctionReturn(0);
2028289bc588SBarry Smith }
2029289bc588SBarry Smith 
2030e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
2031289bc588SBarry Smith {
2032c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
203363ba0a88SBarry Smith   PetscErrorCode ierr;
203467e560aaSBarry Smith 
20353a40ed3dSBarry Smith   PetscFunctionBegin;
2036b5a2b587SKris Buschelman   switch (op) {
2037b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
20384e0d8c25SBarry Smith     aij->roworiented = flg;
2039b5a2b587SKris Buschelman     break;
2040512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
2041b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
20423971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
20438c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
204413fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
2045b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
2046b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
20470f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
20485021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
2049071fcb05SBarry Smith   case MAT_SORTED_FULL:
20505021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
20515021d80fSJed Brown     break;
20525021d80fSJed Brown   case MAT_SPD:
205377e54ba9SKris Buschelman   case MAT_SYMMETRIC:
205477e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
20559a4540c5SBarry Smith   case MAT_HERMITIAN:
20569a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
20575021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
205877e54ba9SKris Buschelman     break;
2059b5a2b587SKris Buschelman   default:
2060e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
20613a40ed3dSBarry Smith   }
20623a40ed3dSBarry Smith   PetscFunctionReturn(0);
2063289bc588SBarry Smith }
2064289bc588SBarry Smith 
2065e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
20666f0a148fSBarry Smith {
2067ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
20686849ba73SBarry Smith   PetscErrorCode ierr;
2069d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
2070ca15aa20SStefano Zampini   PetscScalar    *v;
20713a40ed3dSBarry Smith 
20723a40ed3dSBarry Smith   PetscFunctionBegin;
2073ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2074a5ce6ee0Svictorle   if (lda>m) {
2075d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2076ca15aa20SStefano Zampini       ierr = PetscArrayzero(v+j*lda,m);CHKERRQ(ierr);
2077a5ce6ee0Svictorle     }
2078a5ce6ee0Svictorle   } else {
2079ca15aa20SStefano Zampini     ierr = PetscArrayzero(v,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2080a5ce6ee0Svictorle   }
2081ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
20823a40ed3dSBarry Smith   PetscFunctionReturn(0);
20836f0a148fSBarry Smith }
20846f0a148fSBarry Smith 
2085e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
20866f0a148fSBarry Smith {
208797b48c8fSBarry Smith   PetscErrorCode    ierr;
2088ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
2089b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
2090ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
209197b48c8fSBarry Smith   const PetscScalar *xx;
209255659b69SBarry Smith 
20933a40ed3dSBarry Smith   PetscFunctionBegin;
209476bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2095b9679d65SBarry Smith     for (i=0; i<N; i++) {
2096b9679d65SBarry Smith       if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
2097b9679d65SBarry 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);
2098b9679d65SBarry Smith     }
209976bd3646SJed Brown   }
2100ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
2101b9679d65SBarry Smith 
210297b48c8fSBarry Smith   /* fix right hand side if needed */
210397b48c8fSBarry Smith   if (x && b) {
210497b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
210597b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
21062205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
210797b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
210897b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
210997b48c8fSBarry Smith   }
211097b48c8fSBarry Smith 
2111ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
21126f0a148fSBarry Smith   for (i=0; i<N; i++) {
2113ca15aa20SStefano Zampini     slot = v + rows[i];
2114b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
21156f0a148fSBarry Smith   }
2116f4df32b1SMatthew Knepley   if (diag != 0.0) {
2117b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
21186f0a148fSBarry Smith     for (i=0; i<N; i++) {
2119ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
2120f4df32b1SMatthew Knepley       *slot = diag;
21216f0a148fSBarry Smith     }
21226f0a148fSBarry Smith   }
2123ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
21243a40ed3dSBarry Smith   PetscFunctionReturn(0);
21256f0a148fSBarry Smith }
2126557bce09SLois Curfman McInnes 
212749a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
212849a6ff4bSBarry Smith {
212949a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
213049a6ff4bSBarry Smith 
213149a6ff4bSBarry Smith   PetscFunctionBegin;
213249a6ff4bSBarry Smith   *lda = mat->lda;
213349a6ff4bSBarry Smith   PetscFunctionReturn(0);
213449a6ff4bSBarry Smith }
213549a6ff4bSBarry Smith 
2136637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array)
213764e87e97SBarry Smith {
2138c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
21393a40ed3dSBarry Smith 
21403a40ed3dSBarry Smith   PetscFunctionBegin;
2141616b8fbbSStefano Zampini   if (mat->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
214264e87e97SBarry Smith   *array = mat->v;
21433a40ed3dSBarry Smith   PetscFunctionReturn(0);
214464e87e97SBarry Smith }
21450754003eSLois Curfman McInnes 
2146637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array)
2147ff14e315SSatish Balay {
21483a40ed3dSBarry Smith   PetscFunctionBegin;
2149637a0070SStefano Zampini   *array = NULL;
21503a40ed3dSBarry Smith   PetscFunctionReturn(0);
2151ff14e315SSatish Balay }
21520754003eSLois Curfman McInnes 
2153dec5eb66SMatthew G Knepley /*@C
215449a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
215549a6ff4bSBarry Smith 
2156ad16ce7aSStefano Zampini    Not collective
215749a6ff4bSBarry Smith 
215849a6ff4bSBarry Smith    Input Parameter:
215949a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
216049a6ff4bSBarry Smith 
216149a6ff4bSBarry Smith    Output Parameter:
216249a6ff4bSBarry Smith .   lda - the leading dimension
216349a6ff4bSBarry Smith 
216449a6ff4bSBarry Smith    Level: intermediate
216549a6ff4bSBarry Smith 
2166ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseSetLDA()
216749a6ff4bSBarry Smith @*/
216849a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
216949a6ff4bSBarry Smith {
217049a6ff4bSBarry Smith   PetscErrorCode ierr;
217149a6ff4bSBarry Smith 
217249a6ff4bSBarry Smith   PetscFunctionBegin;
2173d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2174d5ea218eSStefano Zampini   PetscValidPointer(lda,2);
217549a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
217649a6ff4bSBarry Smith   PetscFunctionReturn(0);
217749a6ff4bSBarry Smith }
217849a6ff4bSBarry Smith 
217949a6ff4bSBarry Smith /*@C
2180ad16ce7aSStefano Zampini    MatDenseSetLDA - Sets the leading dimension of the array used by the dense matrix
2181ad16ce7aSStefano Zampini 
2182ad16ce7aSStefano Zampini    Not collective
2183ad16ce7aSStefano Zampini 
2184ad16ce7aSStefano Zampini    Input Parameter:
2185ad16ce7aSStefano Zampini +  mat - a MATSEQDENSE or MATMPIDENSE matrix
2186ad16ce7aSStefano Zampini -  lda - the leading dimension
2187ad16ce7aSStefano Zampini 
2188ad16ce7aSStefano Zampini    Level: intermediate
2189ad16ce7aSStefano Zampini 
2190ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetLDA()
2191ad16ce7aSStefano Zampini @*/
2192ad16ce7aSStefano Zampini PetscErrorCode  MatDenseSetLDA(Mat A,PetscInt lda)
2193ad16ce7aSStefano Zampini {
2194ad16ce7aSStefano Zampini   PetscErrorCode ierr;
2195ad16ce7aSStefano Zampini 
2196ad16ce7aSStefano Zampini   PetscFunctionBegin;
2197ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2198ad16ce7aSStefano Zampini   ierr = PetscTryMethod(A,"MatDenseSetLDA_C",(Mat,PetscInt),(A,lda));CHKERRQ(ierr);
2199ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2200ad16ce7aSStefano Zampini }
2201ad16ce7aSStefano Zampini 
2202ad16ce7aSStefano Zampini /*@C
22036947451fSStefano Zampini    MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored
220473a71a0fSBarry Smith 
22058572280aSBarry Smith    Logically Collective on Mat
220673a71a0fSBarry Smith 
220773a71a0fSBarry Smith    Input Parameter:
22086947451fSStefano Zampini .  mat - a dense matrix
220973a71a0fSBarry Smith 
221073a71a0fSBarry Smith    Output Parameter:
221173a71a0fSBarry Smith .   array - pointer to the data
221273a71a0fSBarry Smith 
221373a71a0fSBarry Smith    Level: intermediate
221473a71a0fSBarry Smith 
22156947451fSStefano Zampini .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
221673a71a0fSBarry Smith @*/
22178c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
221873a71a0fSBarry Smith {
221973a71a0fSBarry Smith   PetscErrorCode ierr;
222073a71a0fSBarry Smith 
222173a71a0fSBarry Smith   PetscFunctionBegin;
2222d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2223d5ea218eSStefano Zampini   PetscValidPointer(array,2);
22248c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
222573a71a0fSBarry Smith   PetscFunctionReturn(0);
222673a71a0fSBarry Smith }
222773a71a0fSBarry Smith 
2228dec5eb66SMatthew G Knepley /*@C
2229579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
223073a71a0fSBarry Smith 
22318572280aSBarry Smith    Logically Collective on Mat
22328572280aSBarry Smith 
22338572280aSBarry Smith    Input Parameters:
22346947451fSStefano Zampini +  mat - a dense matrix
2235a2b725a8SWilliam Gropp -  array - pointer to the data
22368572280aSBarry Smith 
22378572280aSBarry Smith    Level: intermediate
22388572280aSBarry Smith 
22396947451fSStefano Zampini .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
22408572280aSBarry Smith @*/
22418572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
22428572280aSBarry Smith {
22438572280aSBarry Smith   PetscErrorCode ierr;
22448572280aSBarry Smith 
22458572280aSBarry Smith   PetscFunctionBegin;
2246d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2247d5ea218eSStefano Zampini   PetscValidPointer(array,2);
22488572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
22498572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
2250637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
2251637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2252637a0070SStefano Zampini #endif
22538572280aSBarry Smith   PetscFunctionReturn(0);
22548572280aSBarry Smith }
22558572280aSBarry Smith 
22568572280aSBarry Smith /*@C
22576947451fSStefano Zampini    MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored
22588572280aSBarry Smith 
22598572280aSBarry Smith    Not Collective
22608572280aSBarry Smith 
22618572280aSBarry Smith    Input Parameter:
22626947451fSStefano Zampini .  mat - a dense matrix
22638572280aSBarry Smith 
22648572280aSBarry Smith    Output Parameter:
22658572280aSBarry Smith .   array - pointer to the data
22668572280aSBarry Smith 
22678572280aSBarry Smith    Level: intermediate
22688572280aSBarry Smith 
22696947451fSStefano Zampini .seealso: MatDenseRestoreArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
22708572280aSBarry Smith @*/
22718572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
22728572280aSBarry Smith {
22738572280aSBarry Smith   PetscErrorCode ierr;
22748572280aSBarry Smith 
22758572280aSBarry Smith   PetscFunctionBegin;
2276d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2277d5ea218eSStefano Zampini   PetscValidPointer(array,2);
22788572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
22798572280aSBarry Smith   PetscFunctionReturn(0);
22808572280aSBarry Smith }
22818572280aSBarry Smith 
22828572280aSBarry Smith /*@C
22836947451fSStefano Zampini    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead()
22848572280aSBarry Smith 
228573a71a0fSBarry Smith    Not Collective
228673a71a0fSBarry Smith 
228773a71a0fSBarry Smith    Input Parameters:
22886947451fSStefano Zampini +  mat - a dense matrix
2289a2b725a8SWilliam Gropp -  array - pointer to the data
229073a71a0fSBarry Smith 
229173a71a0fSBarry Smith    Level: intermediate
229273a71a0fSBarry Smith 
22936947451fSStefano Zampini .seealso: MatDenseGetArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
229473a71a0fSBarry Smith @*/
22958572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
229673a71a0fSBarry Smith {
229773a71a0fSBarry Smith   PetscErrorCode ierr;
229873a71a0fSBarry Smith 
229973a71a0fSBarry Smith   PetscFunctionBegin;
2300d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2301d5ea218eSStefano Zampini   PetscValidPointer(array,2);
23028572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
230373a71a0fSBarry Smith   PetscFunctionReturn(0);
230473a71a0fSBarry Smith }
230573a71a0fSBarry Smith 
23066947451fSStefano Zampini /*@C
23076947451fSStefano Zampini    MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored
23086947451fSStefano Zampini 
23096947451fSStefano Zampini    Not Collective
23106947451fSStefano Zampini 
23116947451fSStefano Zampini    Input Parameter:
23126947451fSStefano Zampini .  mat - a dense matrix
23136947451fSStefano Zampini 
23146947451fSStefano Zampini    Output Parameter:
23156947451fSStefano Zampini .   array - pointer to the data
23166947451fSStefano Zampini 
23176947451fSStefano Zampini    Level: intermediate
23186947451fSStefano Zampini 
23196947451fSStefano Zampini .seealso: MatDenseRestoreArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
23206947451fSStefano Zampini @*/
23216947451fSStefano Zampini PetscErrorCode  MatDenseGetArrayWrite(Mat A,PetscScalar **array)
23226947451fSStefano Zampini {
23236947451fSStefano Zampini   PetscErrorCode ierr;
23246947451fSStefano Zampini 
23256947451fSStefano Zampini   PetscFunctionBegin;
2326d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2327d5ea218eSStefano Zampini   PetscValidPointer(array,2);
23286947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
23296947451fSStefano Zampini   PetscFunctionReturn(0);
23306947451fSStefano Zampini }
23316947451fSStefano Zampini 
23326947451fSStefano Zampini /*@C
23336947451fSStefano Zampini    MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite()
23346947451fSStefano Zampini 
23356947451fSStefano Zampini    Not Collective
23366947451fSStefano Zampini 
23376947451fSStefano Zampini    Input Parameters:
23386947451fSStefano Zampini +  mat - a dense matrix
23396947451fSStefano Zampini -  array - pointer to the data
23406947451fSStefano Zampini 
23416947451fSStefano Zampini    Level: intermediate
23426947451fSStefano Zampini 
23436947451fSStefano Zampini .seealso: MatDenseGetArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
23446947451fSStefano Zampini @*/
23456947451fSStefano Zampini PetscErrorCode  MatDenseRestoreArrayWrite(Mat A,PetscScalar **array)
23466947451fSStefano Zampini {
23476947451fSStefano Zampini   PetscErrorCode ierr;
23486947451fSStefano Zampini 
23496947451fSStefano Zampini   PetscFunctionBegin;
2350d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2351d5ea218eSStefano Zampini   PetscValidPointer(array,2);
23526947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
23536947451fSStefano Zampini   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
23546947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
23556947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
23566947451fSStefano Zampini #endif
23576947451fSStefano Zampini   PetscFunctionReturn(0);
23586947451fSStefano Zampini }
23596947451fSStefano Zampini 
2360023c16fcSToby Isaac static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,MatReuse scall,Mat *B)
23610754003eSLois Curfman McInnes {
2362c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
23636849ba73SBarry Smith   PetscErrorCode ierr;
2364ca15aa20SStefano Zampini   PetscInt       i,j,nrows,ncols,blda;
23655d0c19d7SBarry Smith   const PetscInt *irow,*icol;
236687828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
23670754003eSLois Curfman McInnes   Mat            newmat;
23680754003eSLois Curfman McInnes 
23693a40ed3dSBarry Smith   PetscFunctionBegin;
237078b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
237178b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
2372e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2373e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
23740754003eSLois Curfman McInnes 
2375182d2002SSatish Balay   /* Check submatrixcall */
2376182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
237713f74950SBarry Smith     PetscInt n_cols,n_rows;
2378182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
237921a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2380f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
2381c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
238221a2c019SBarry Smith     }
2383182d2002SSatish Balay     newmat = *B;
2384182d2002SSatish Balay   } else {
23850754003eSLois Curfman McInnes     /* Create and fill new matrix */
2386ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
2387f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
23887adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
23890298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
2390182d2002SSatish Balay   }
2391182d2002SSatish Balay 
2392182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
2393ca15aa20SStefano Zampini   ierr = MatDenseGetArray(newmat,&bv);CHKERRQ(ierr);
2394ca15aa20SStefano Zampini   ierr = MatDenseGetLDA(newmat,&blda);CHKERRQ(ierr);
2395182d2002SSatish Balay   for (i=0; i<ncols; i++) {
23966de62eeeSBarry Smith     av = v + mat->lda*icol[i];
2397ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
2398ca15aa20SStefano Zampini     bv += blda;
23990754003eSLois Curfman McInnes   }
2400ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(newmat,&bv);CHKERRQ(ierr);
2401182d2002SSatish Balay 
2402182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
24036d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24046d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24050754003eSLois Curfman McInnes 
24060754003eSLois Curfman McInnes   /* Free work space */
240778b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
240878b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2409182d2002SSatish Balay   *B   = newmat;
24103a40ed3dSBarry Smith   PetscFunctionReturn(0);
24110754003eSLois Curfman McInnes }
24120754003eSLois Curfman McInnes 
24137dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2414905e6a2fSBarry Smith {
24156849ba73SBarry Smith   PetscErrorCode ierr;
241613f74950SBarry Smith   PetscInt       i;
2417905e6a2fSBarry Smith 
24183a40ed3dSBarry Smith   PetscFunctionBegin;
2419905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2420df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
2421905e6a2fSBarry Smith   }
2422905e6a2fSBarry Smith 
2423905e6a2fSBarry Smith   for (i=0; i<n; i++) {
2424023c16fcSToby Isaac     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],scall,&(*B)[i]);CHKERRQ(ierr);
2425905e6a2fSBarry Smith   }
24263a40ed3dSBarry Smith   PetscFunctionReturn(0);
2427905e6a2fSBarry Smith }
2428905e6a2fSBarry Smith 
2429e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2430c0aa2d19SHong Zhang {
2431c0aa2d19SHong Zhang   PetscFunctionBegin;
2432c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2433c0aa2d19SHong Zhang }
2434c0aa2d19SHong Zhang 
2435e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2436c0aa2d19SHong Zhang {
2437c0aa2d19SHong Zhang   PetscFunctionBegin;
2438c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2439c0aa2d19SHong Zhang }
2440c0aa2d19SHong Zhang 
2441a76f77c3SStefano Zampini PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
24424b0e389bSBarry Smith {
24434b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
24446849ba73SBarry Smith   PetscErrorCode    ierr;
2445ca15aa20SStefano Zampini   const PetscScalar *va;
2446ca15aa20SStefano Zampini   PetscScalar       *vb;
2447d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
24483a40ed3dSBarry Smith 
24493a40ed3dSBarry Smith   PetscFunctionBegin;
245033f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
245133f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
2452cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
24533a40ed3dSBarry Smith     PetscFunctionReturn(0);
24543a40ed3dSBarry Smith   }
2455e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
2456ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&va);CHKERRQ(ierr);
2457ca15aa20SStefano Zampini   ierr = MatDenseGetArray(B,&vb);CHKERRQ(ierr);
2458a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
24590dbb7854Svictorle     for (j=0; j<n; j++) {
2460ca15aa20SStefano Zampini       ierr = PetscArraycpy(vb+j*lda2,va+j*lda1,m);CHKERRQ(ierr);
2461a5ce6ee0Svictorle     }
2462a5ce6ee0Svictorle   } else {
2463ca15aa20SStefano Zampini     ierr = PetscArraycpy(vb,va,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2464a5ce6ee0Svictorle   }
2465ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(B,&vb);CHKERRQ(ierr);
2466ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&va);CHKERRQ(ierr);
2467ca15aa20SStefano Zampini   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2468ca15aa20SStefano Zampini   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2469273d9f13SBarry Smith   PetscFunctionReturn(0);
2470273d9f13SBarry Smith }
2471273d9f13SBarry Smith 
2472e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
2473273d9f13SBarry Smith {
2474dfbe8321SBarry Smith   PetscErrorCode ierr;
2475273d9f13SBarry Smith 
2476273d9f13SBarry Smith   PetscFunctionBegin;
247718992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
247818992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
247918992e5dSStefano Zampini   if (!A->preallocated) {
2480f4259b30SLisandro Dalcin     ierr = MatSeqDenseSetPreallocation(A,NULL);CHKERRQ(ierr);
248118992e5dSStefano Zampini   }
24823a40ed3dSBarry Smith   PetscFunctionReturn(0);
24834b0e389bSBarry Smith }
24844b0e389bSBarry Smith 
2485ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2486ba337c44SJed Brown {
2487*4396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
2488ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2489*4396437dSToby Isaac   PetscInt       min = PetscMin(A->rmap->n,A->cmap->n);
2490ca15aa20SStefano Zampini   PetscScalar    *aa;
2491ca15aa20SStefano Zampini   PetscErrorCode ierr;
2492ba337c44SJed Brown 
2493ba337c44SJed Brown   PetscFunctionBegin;
2494ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2495ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2496ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2497*4396437dSToby Isaac   if (mat->tau) for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2498ba337c44SJed Brown   PetscFunctionReturn(0);
2499ba337c44SJed Brown }
2500ba337c44SJed Brown 
2501ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2502ba337c44SJed Brown {
2503ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2504ca15aa20SStefano Zampini   PetscScalar    *aa;
2505ca15aa20SStefano Zampini   PetscErrorCode ierr;
2506ba337c44SJed Brown 
2507ba337c44SJed Brown   PetscFunctionBegin;
2508ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2509ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2510ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2511ba337c44SJed Brown   PetscFunctionReturn(0);
2512ba337c44SJed Brown }
2513ba337c44SJed Brown 
2514ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2515ba337c44SJed Brown {
2516ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2517ca15aa20SStefano Zampini   PetscScalar    *aa;
2518ca15aa20SStefano Zampini   PetscErrorCode ierr;
2519ba337c44SJed Brown 
2520ba337c44SJed Brown   PetscFunctionBegin;
2521ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2522ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
2523ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2524ba337c44SJed Brown   PetscFunctionReturn(0);
2525ba337c44SJed Brown }
2526284134d9SBarry Smith 
2527a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
25284222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2529a9fe9ddaSSatish Balay {
2530ee16a9a1SHong Zhang   PetscErrorCode ierr;
2531d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
25327a3c3d58SStefano Zampini   PetscBool      cisdense;
2533a9fe9ddaSSatish Balay 
2534ee16a9a1SHong Zhang   PetscFunctionBegin;
25354222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
25367a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
25377a3c3d58SStefano Zampini   if (!cisdense) {
25387a3c3d58SStefano Zampini     PetscBool flg;
25397a3c3d58SStefano Zampini 
2540ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
25414222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
25427a3c3d58SStefano Zampini   }
254318992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2544ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2545ee16a9a1SHong Zhang }
2546a9fe9ddaSSatish Balay 
2547a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2548a9fe9ddaSSatish Balay {
25496718818eSStefano Zampini   Mat_SeqDense       *a=(Mat_SeqDense*)A->data,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
25500805154bSBarry Smith   PetscBLASInt       m,n,k;
2551ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2552ca15aa20SStefano Zampini   PetscScalar       *cv;
2553a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2554c2916339SPierre Jolivet   PetscErrorCode    ierr;
2555a9fe9ddaSSatish Balay 
2556a9fe9ddaSSatish Balay   PetscFunctionBegin;
25578208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
25588208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2559c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
256049d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
2561ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
2562ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
25636718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
2564ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
2565ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2566ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
2567ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
25686718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2569a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2570a9fe9ddaSSatish Balay }
2571a9fe9ddaSSatish Balay 
25724222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
257369f65d41SStefano Zampini {
257469f65d41SStefano Zampini   PetscErrorCode ierr;
257569f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
25767a3c3d58SStefano Zampini   PetscBool      cisdense;
257769f65d41SStefano Zampini 
257869f65d41SStefano Zampini   PetscFunctionBegin;
25794222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
25807a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
25817a3c3d58SStefano Zampini   if (!cisdense) {
25827a3c3d58SStefano Zampini     PetscBool flg;
25837a3c3d58SStefano Zampini 
2584ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
25854222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
25867a3c3d58SStefano Zampini   }
258718992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
258869f65d41SStefano Zampini   PetscFunctionReturn(0);
258969f65d41SStefano Zampini }
259069f65d41SStefano Zampini 
259169f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
259269f65d41SStefano Zampini {
259369f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
259469f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
259569f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
25966718818eSStefano Zampini   const PetscScalar *av,*bv;
25976718818eSStefano Zampini   PetscScalar       *cv;
259869f65d41SStefano Zampini   PetscBLASInt      m,n,k;
259969f65d41SStefano Zampini   PetscScalar       _DOne=1.0,_DZero=0.0;
260069f65d41SStefano Zampini   PetscErrorCode    ierr;
260169f65d41SStefano Zampini 
260269f65d41SStefano Zampini   PetscFunctionBegin;
260349d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
260449d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
260569f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
260649d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
26076718818eSStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
26086718818eSStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
26096718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
26106718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
26116718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
26126718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
26136718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2614ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
261569f65d41SStefano Zampini   PetscFunctionReturn(0);
261669f65d41SStefano Zampini }
261769f65d41SStefano Zampini 
26184222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2619a9fe9ddaSSatish Balay {
2620ee16a9a1SHong Zhang   PetscErrorCode ierr;
2621d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
26227a3c3d58SStefano Zampini   PetscBool      cisdense;
2623a9fe9ddaSSatish Balay 
2624ee16a9a1SHong Zhang   PetscFunctionBegin;
26254222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
26267a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
26277a3c3d58SStefano Zampini   if (!cisdense) {
26287a3c3d58SStefano Zampini     PetscBool flg;
26297a3c3d58SStefano Zampini 
2630ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
26314222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
26327a3c3d58SStefano Zampini   }
263318992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2634ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2635ee16a9a1SHong Zhang }
2636a9fe9ddaSSatish Balay 
263775648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2638a9fe9ddaSSatish Balay {
2639a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2640a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
2641a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
26426718818eSStefano Zampini   const PetscScalar *av,*bv;
26436718818eSStefano Zampini   PetscScalar       *cv;
26440805154bSBarry Smith   PetscBLASInt      m,n,k;
2645a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2646c5df96a5SBarry Smith   PetscErrorCode    ierr;
2647a9fe9ddaSSatish Balay 
2648a9fe9ddaSSatish Balay   PetscFunctionBegin;
26498208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
26508208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2651c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
265249d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
26536718818eSStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
26546718818eSStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
26556718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
26566718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
26576718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
26586718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
26596718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2660ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2661a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2662a9fe9ddaSSatish Balay }
2663985db425SBarry Smith 
26644222ddf1SHong Zhang /* ----------------------------------------------- */
26654222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
26664222ddf1SHong Zhang {
26674222ddf1SHong Zhang   PetscFunctionBegin;
26684222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
26694222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
26704222ddf1SHong Zhang   PetscFunctionReturn(0);
26714222ddf1SHong Zhang }
26724222ddf1SHong Zhang 
26734222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
26744222ddf1SHong Zhang {
26754222ddf1SHong Zhang   PetscFunctionBegin;
26764222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
26774222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
26784222ddf1SHong Zhang   PetscFunctionReturn(0);
26794222ddf1SHong Zhang }
26804222ddf1SHong Zhang 
26814222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
26824222ddf1SHong Zhang {
26834222ddf1SHong Zhang   PetscFunctionBegin;
26844222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
26854222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
26864222ddf1SHong Zhang   PetscFunctionReturn(0);
26874222ddf1SHong Zhang }
26884222ddf1SHong Zhang 
26894222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
26904222ddf1SHong Zhang {
26914222ddf1SHong Zhang   PetscErrorCode ierr;
26924222ddf1SHong Zhang   Mat_Product    *product = C->product;
26934222ddf1SHong Zhang 
26944222ddf1SHong Zhang   PetscFunctionBegin;
26954222ddf1SHong Zhang   switch (product->type) {
26964222ddf1SHong Zhang   case MATPRODUCT_AB:
26974222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AB(C);CHKERRQ(ierr);
26984222ddf1SHong Zhang     break;
26994222ddf1SHong Zhang   case MATPRODUCT_AtB:
27004222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AtB(C);CHKERRQ(ierr);
27014222ddf1SHong Zhang     break;
27024222ddf1SHong Zhang   case MATPRODUCT_ABt:
27034222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_ABt(C);CHKERRQ(ierr);
27044222ddf1SHong Zhang     break;
27056718818eSStefano Zampini   default:
27064222ddf1SHong Zhang     break;
27074222ddf1SHong Zhang   }
27084222ddf1SHong Zhang   PetscFunctionReturn(0);
27094222ddf1SHong Zhang }
27104222ddf1SHong Zhang /* ----------------------------------------------- */
27114222ddf1SHong Zhang 
2712e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2713985db425SBarry Smith {
2714985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2715985db425SBarry Smith   PetscErrorCode     ierr;
2716d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2717985db425SBarry Smith   PetscScalar        *x;
2718ca15aa20SStefano Zampini   const PetscScalar *aa;
2719985db425SBarry Smith 
2720985db425SBarry Smith   PetscFunctionBegin;
2721e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2722985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2723985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2724ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2725e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2726985db425SBarry Smith   for (i=0; i<m; i++) {
2727985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2728985db425SBarry Smith     for (j=1; j<n; j++) {
2729ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2730985db425SBarry Smith     }
2731985db425SBarry Smith   }
2732ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2733985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2734985db425SBarry Smith   PetscFunctionReturn(0);
2735985db425SBarry Smith }
2736985db425SBarry Smith 
2737e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2738985db425SBarry Smith {
2739985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2740985db425SBarry Smith   PetscErrorCode    ierr;
2741d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2742985db425SBarry Smith   PetscScalar       *x;
2743985db425SBarry Smith   PetscReal         atmp;
2744ca15aa20SStefano Zampini   const PetscScalar *aa;
2745985db425SBarry Smith 
2746985db425SBarry Smith   PetscFunctionBegin;
2747e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2748985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2749985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2750ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2751e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2752985db425SBarry Smith   for (i=0; i<m; i++) {
27539189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2754985db425SBarry Smith     for (j=1; j<n; j++) {
2755ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2756985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2757985db425SBarry Smith     }
2758985db425SBarry Smith   }
2759ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2760985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2761985db425SBarry Smith   PetscFunctionReturn(0);
2762985db425SBarry Smith }
2763985db425SBarry Smith 
2764e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2765985db425SBarry Smith {
2766985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2767985db425SBarry Smith   PetscErrorCode    ierr;
2768d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2769985db425SBarry Smith   PetscScalar       *x;
2770ca15aa20SStefano Zampini   const PetscScalar *aa;
2771985db425SBarry Smith 
2772985db425SBarry Smith   PetscFunctionBegin;
2773e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2774ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2775985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2776985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2777e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2778985db425SBarry Smith   for (i=0; i<m; i++) {
2779985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2780985db425SBarry Smith     for (j=1; j<n; j++) {
2781ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2782985db425SBarry Smith     }
2783985db425SBarry Smith   }
2784985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2785ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2786985db425SBarry Smith   PetscFunctionReturn(0);
2787985db425SBarry Smith }
2788985db425SBarry Smith 
2789637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
27908d0534beSBarry Smith {
27918d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
27928d0534beSBarry Smith   PetscErrorCode    ierr;
27938d0534beSBarry Smith   PetscScalar       *x;
2794ca15aa20SStefano Zampini   const PetscScalar *aa;
27958d0534beSBarry Smith 
27968d0534beSBarry Smith   PetscFunctionBegin;
2797e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2798ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
27998d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2800ca15aa20SStefano Zampini   ierr = PetscArraycpy(x,aa+col*a->lda,A->rmap->n);CHKERRQ(ierr);
28018d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2802ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
28038d0534beSBarry Smith   PetscFunctionReturn(0);
28048d0534beSBarry Smith }
28058d0534beSBarry Smith 
280652c5f739Sprj- PETSC_INTERN PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
28070716a85fSBarry Smith {
28080716a85fSBarry Smith   PetscErrorCode    ierr;
28090716a85fSBarry Smith   PetscInt          i,j,m,n;
28101683a169SBarry Smith   const PetscScalar *a;
28110716a85fSBarry Smith 
28120716a85fSBarry Smith   PetscFunctionBegin;
28130716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2814580bdb30SBarry Smith   ierr = PetscArrayzero(norms,n);CHKERRQ(ierr);
28151683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&a);CHKERRQ(ierr);
28160716a85fSBarry Smith   if (type == NORM_2) {
28170716a85fSBarry Smith     for (i=0; i<n; i++) {
28180716a85fSBarry Smith       for (j=0; j<m; j++) {
28190716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
28200716a85fSBarry Smith       }
28210716a85fSBarry Smith       a += m;
28220716a85fSBarry Smith     }
28230716a85fSBarry Smith   } else if (type == NORM_1) {
28240716a85fSBarry Smith     for (i=0; i<n; i++) {
28250716a85fSBarry Smith       for (j=0; j<m; j++) {
28260716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
28270716a85fSBarry Smith       }
28280716a85fSBarry Smith       a += m;
28290716a85fSBarry Smith     }
28300716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
28310716a85fSBarry Smith     for (i=0; i<n; i++) {
28320716a85fSBarry Smith       for (j=0; j<m; j++) {
28330716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
28340716a85fSBarry Smith       }
28350716a85fSBarry Smith       a += m;
28360716a85fSBarry Smith     }
2837ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
28381683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&a);CHKERRQ(ierr);
28390716a85fSBarry Smith   if (type == NORM_2) {
28408f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
28410716a85fSBarry Smith   }
28420716a85fSBarry Smith   PetscFunctionReturn(0);
28430716a85fSBarry Smith }
28440716a85fSBarry Smith 
284573a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
284673a71a0fSBarry Smith {
284773a71a0fSBarry Smith   PetscErrorCode ierr;
284873a71a0fSBarry Smith   PetscScalar    *a;
2849637a0070SStefano Zampini   PetscInt       lda,m,n,i,j;
285073a71a0fSBarry Smith 
285173a71a0fSBarry Smith   PetscFunctionBegin;
285273a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
2853637a0070SStefano Zampini   ierr = MatDenseGetLDA(x,&lda);CHKERRQ(ierr);
28548c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
2855637a0070SStefano Zampini   for (j=0; j<n; j++) {
2856637a0070SStefano Zampini     for (i=0; i<m; i++) {
2857637a0070SStefano Zampini       ierr = PetscRandomGetValue(rctx,a+j*lda+i);CHKERRQ(ierr);
2858637a0070SStefano Zampini     }
285973a71a0fSBarry Smith   }
28608c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
286173a71a0fSBarry Smith   PetscFunctionReturn(0);
286273a71a0fSBarry Smith }
286373a71a0fSBarry Smith 
28643b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
28653b49f96aSBarry Smith {
28663b49f96aSBarry Smith   PetscFunctionBegin;
28673b49f96aSBarry Smith   *missing = PETSC_FALSE;
28683b49f96aSBarry Smith   PetscFunctionReturn(0);
28693b49f96aSBarry Smith }
287073a71a0fSBarry Smith 
2871ca15aa20SStefano Zampini /* vals is not const */
2872af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
287386aefd0dSHong Zhang {
2874ca15aa20SStefano Zampini   PetscErrorCode ierr;
287586aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2876ca15aa20SStefano Zampini   PetscScalar    *v;
287786aefd0dSHong Zhang 
287886aefd0dSHong Zhang   PetscFunctionBegin;
287986aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2880ca15aa20SStefano Zampini   ierr  = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2881ca15aa20SStefano Zampini   *vals = v+col*a->lda;
2882ca15aa20SStefano Zampini   ierr  = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
288386aefd0dSHong Zhang   PetscFunctionReturn(0);
288486aefd0dSHong Zhang }
288586aefd0dSHong Zhang 
2886af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
288786aefd0dSHong Zhang {
288886aefd0dSHong Zhang   PetscFunctionBegin;
2889f4259b30SLisandro Dalcin   *vals = NULL; /* user cannot accidently use the array later */
289086aefd0dSHong Zhang   PetscFunctionReturn(0);
289186aefd0dSHong Zhang }
2892abc3b08eSStefano Zampini 
2893289bc588SBarry Smith /* -------------------------------------------------------------------*/
2894a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2895905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2896905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2897905e6a2fSBarry Smith                                         MatMult_SeqDense,
289897304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
28997c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
29007c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2901f4259b30SLisandro Dalcin                                         NULL,
2902f4259b30SLisandro Dalcin                                         NULL,
2903f4259b30SLisandro Dalcin                                         NULL,
2904f4259b30SLisandro Dalcin                                 /* 10*/ NULL,
2905905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2906905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
290741f059aeSBarry Smith                                         MatSOR_SeqDense,
2908ec8511deSBarry Smith                                         MatTranspose_SeqDense,
290997304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2910905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2911905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2912905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2913905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2914c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2915c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2916905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2917905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2918d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2919f4259b30SLisandro Dalcin                                         NULL,
2920f4259b30SLisandro Dalcin                                         NULL,
2921f4259b30SLisandro Dalcin                                         NULL,
2922f4259b30SLisandro Dalcin                                         NULL,
29234994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2924f4259b30SLisandro Dalcin                                         NULL,
2925f4259b30SLisandro Dalcin                                         NULL,
2926f4259b30SLisandro Dalcin                                         NULL,
2927f4259b30SLisandro Dalcin                                         NULL,
2928d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2929f4259b30SLisandro Dalcin                                         NULL,
2930f4259b30SLisandro Dalcin                                         NULL,
2931f4259b30SLisandro Dalcin                                         NULL,
2932f4259b30SLisandro Dalcin                                         NULL,
2933d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
29347dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2935f4259b30SLisandro Dalcin                                         NULL,
29364b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2937a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2938d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2939a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
29407d68702bSBarry Smith                                         MatShift_Basic,
2941f4259b30SLisandro Dalcin                                         NULL,
29423f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
294373a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2944f4259b30SLisandro Dalcin                                         NULL,
2945f4259b30SLisandro Dalcin                                         NULL,
2946f4259b30SLisandro Dalcin                                         NULL,
2947f4259b30SLisandro Dalcin                                         NULL,
2948f4259b30SLisandro Dalcin                                 /* 54*/ NULL,
2949f4259b30SLisandro Dalcin                                         NULL,
2950f4259b30SLisandro Dalcin                                         NULL,
2951f4259b30SLisandro Dalcin                                         NULL,
2952f4259b30SLisandro Dalcin                                         NULL,
2953023c16fcSToby Isaac                                 /* 59*/ MatCreateSubMatrix_SeqDense,
2954e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2955e03a110bSBarry Smith                                         MatView_SeqDense,
2956f4259b30SLisandro Dalcin                                         NULL,
2957f4259b30SLisandro Dalcin                                         NULL,
2958f4259b30SLisandro Dalcin                                 /* 64*/ NULL,
2959f4259b30SLisandro Dalcin                                         NULL,
2960f4259b30SLisandro Dalcin                                         NULL,
2961f4259b30SLisandro Dalcin                                         NULL,
2962f4259b30SLisandro Dalcin                                         NULL,
2963d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
2964f4259b30SLisandro Dalcin                                         NULL,
2965f4259b30SLisandro Dalcin                                         NULL,
2966f4259b30SLisandro Dalcin                                         NULL,
2967f4259b30SLisandro Dalcin                                         NULL,
2968f4259b30SLisandro Dalcin                                 /* 74*/ NULL,
2969f4259b30SLisandro Dalcin                                         NULL,
2970f4259b30SLisandro Dalcin                                         NULL,
2971f4259b30SLisandro Dalcin                                         NULL,
2972f4259b30SLisandro Dalcin                                         NULL,
2973f4259b30SLisandro Dalcin                                 /* 79*/ NULL,
2974f4259b30SLisandro Dalcin                                         NULL,
2975f4259b30SLisandro Dalcin                                         NULL,
2976f4259b30SLisandro Dalcin                                         NULL,
29775bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2978637a0070SStefano Zampini                                         MatIsSymmetric_SeqDense,
29791cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2980f4259b30SLisandro Dalcin                                         NULL,
2981f4259b30SLisandro Dalcin                                         NULL,
2982f4259b30SLisandro Dalcin                                         NULL,
2983f4259b30SLisandro Dalcin                                 /* 89*/ NULL,
2984f4259b30SLisandro Dalcin                                         NULL,
2985a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2986f4259b30SLisandro Dalcin                                         NULL,
2987f4259b30SLisandro Dalcin                                         NULL,
2988f4259b30SLisandro Dalcin                                 /* 94*/ NULL,
2989f4259b30SLisandro Dalcin                                         NULL,
2990f4259b30SLisandro Dalcin                                         NULL,
299169f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2992f4259b30SLisandro Dalcin                                         NULL,
29934222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
2994f4259b30SLisandro Dalcin                                         NULL,
2995f4259b30SLisandro Dalcin                                         NULL,
2996ba337c44SJed Brown                                         MatConjugate_SeqDense,
2997f4259b30SLisandro Dalcin                                         NULL,
2998f4259b30SLisandro Dalcin                                 /*104*/ NULL,
2999ba337c44SJed Brown                                         MatRealPart_SeqDense,
3000ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
3001f4259b30SLisandro Dalcin                                         NULL,
3002f4259b30SLisandro Dalcin                                         NULL,
3003f4259b30SLisandro Dalcin                                 /*109*/ NULL,
3004f4259b30SLisandro Dalcin                                         NULL,
30058d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
3006aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
30073b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
3008f4259b30SLisandro Dalcin                                 /*114*/ NULL,
3009f4259b30SLisandro Dalcin                                         NULL,
3010f4259b30SLisandro Dalcin                                         NULL,
3011f4259b30SLisandro Dalcin                                         NULL,
3012f4259b30SLisandro Dalcin                                         NULL,
3013f4259b30SLisandro Dalcin                                 /*119*/ NULL,
3014f4259b30SLisandro Dalcin                                         NULL,
3015f4259b30SLisandro Dalcin                                         NULL,
3016f4259b30SLisandro Dalcin                                         NULL,
3017f4259b30SLisandro Dalcin                                         NULL,
3018f4259b30SLisandro Dalcin                                 /*124*/ NULL,
30195df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
3020f4259b30SLisandro Dalcin                                         NULL,
3021f4259b30SLisandro Dalcin                                         NULL,
3022f4259b30SLisandro Dalcin                                         NULL,
3023f4259b30SLisandro Dalcin                                 /*129*/ NULL,
3024f4259b30SLisandro Dalcin                                         NULL,
3025f4259b30SLisandro Dalcin                                         NULL,
302675648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
3027f4259b30SLisandro Dalcin                                         NULL,
3028f4259b30SLisandro Dalcin                                 /*134*/ NULL,
3029f4259b30SLisandro Dalcin                                         NULL,
3030f4259b30SLisandro Dalcin                                         NULL,
3031f4259b30SLisandro Dalcin                                         NULL,
3032f4259b30SLisandro Dalcin                                         NULL,
3033f4259b30SLisandro Dalcin                                 /*139*/ NULL,
3034f4259b30SLisandro Dalcin                                         NULL,
3035f4259b30SLisandro Dalcin                                         NULL,
3036f4259b30SLisandro Dalcin                                         NULL,
3037f4259b30SLisandro Dalcin                                         NULL,
30384222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
3039f4259b30SLisandro Dalcin                                 /*145*/ NULL,
3040f4259b30SLisandro Dalcin                                         NULL,
3041f4259b30SLisandro Dalcin                                         NULL
3042985db425SBarry Smith };
304390ace30eSBarry Smith 
30444b828684SBarry Smith /*@C
3045fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
3046d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
3047d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
3048289bc588SBarry Smith 
3049d083f849SBarry Smith    Collective
3050db81eaa0SLois Curfman McInnes 
305120563c6bSBarry Smith    Input Parameters:
3052db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
30530c775827SLois Curfman McInnes .  m - number of rows
305418f449edSLois Curfman McInnes .  n - number of columns
30550298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
3056dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
305720563c6bSBarry Smith 
305820563c6bSBarry Smith    Output Parameter:
305944cd7ae7SLois Curfman McInnes .  A - the matrix
306020563c6bSBarry Smith 
3061b259b22eSLois Curfman McInnes    Notes:
306218f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
306318f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
30640298fd71SBarry Smith    set data=NULL.
306518f449edSLois Curfman McInnes 
3066027ccd11SLois Curfman McInnes    Level: intermediate
3067027ccd11SLois Curfman McInnes 
306869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
306920563c6bSBarry Smith @*/
30707087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
3071289bc588SBarry Smith {
3072dfbe8321SBarry Smith   PetscErrorCode ierr;
30733b2fbd54SBarry Smith 
30743a40ed3dSBarry Smith   PetscFunctionBegin;
3075f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3076f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3077273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
3078273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
3079273d9f13SBarry Smith   PetscFunctionReturn(0);
3080273d9f13SBarry Smith }
3081273d9f13SBarry Smith 
3082273d9f13SBarry Smith /*@C
3083273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
3084273d9f13SBarry Smith 
3085d083f849SBarry Smith    Collective
3086273d9f13SBarry Smith 
3087273d9f13SBarry Smith    Input Parameters:
30881c4f3114SJed Brown +  B - the matrix
30890298fd71SBarry Smith -  data - the array (or NULL)
3090273d9f13SBarry Smith 
3091273d9f13SBarry Smith    Notes:
3092273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
3093273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
3094284134d9SBarry Smith    need not call this routine.
3095273d9f13SBarry Smith 
3096273d9f13SBarry Smith    Level: intermediate
3097273d9f13SBarry Smith 
3098ad16ce7aSStefano Zampini .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatDenseSetLDA()
3099867c911aSBarry Smith 
3100273d9f13SBarry Smith @*/
31017087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
3102273d9f13SBarry Smith {
31034ac538c5SBarry Smith   PetscErrorCode ierr;
3104a23d5eceSKris Buschelman 
3105a23d5eceSKris Buschelman   PetscFunctionBegin;
3106d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
31074ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
3108a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3109a23d5eceSKris Buschelman }
3110a23d5eceSKris Buschelman 
31117087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
3112a23d5eceSKris Buschelman {
3113ad16ce7aSStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
3114dfbe8321SBarry Smith   PetscErrorCode ierr;
3115273d9f13SBarry Smith 
3116273d9f13SBarry Smith   PetscFunctionBegin;
3117616b8fbbSStefano Zampini   if (b->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
3118273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3119a868139aSShri Abhyankar 
312034ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
312134ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
312234ef9618SShri Abhyankar 
3123ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
312486d161a7SShri Abhyankar 
3125ad16ce7aSStefano Zampini   ierr = PetscIntMultError(b->lda,B->cmap->n,NULL);CHKERRQ(ierr);
31269e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
31279e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
3128ad16ce7aSStefano Zampini     ierr = PetscCalloc1((size_t)b->lda*B->cmap->n,&b->v);CHKERRQ(ierr);
3129ad16ce7aSStefano Zampini     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*B->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
31302205254eSKarl Rupp 
31319e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
3132273d9f13SBarry Smith   } else { /* user-allocated storage */
31339e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
3134273d9f13SBarry Smith     b->v          = data;
3135273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
3136273d9f13SBarry Smith   }
31370450473dSBarry Smith   B->assembled = PETSC_TRUE;
3138273d9f13SBarry Smith   PetscFunctionReturn(0);
3139273d9f13SBarry Smith }
3140273d9f13SBarry Smith 
314165b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3142cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
31438baccfbdSHong Zhang {
3144d77f618aSHong Zhang   Mat               mat_elemental;
3145d77f618aSHong Zhang   PetscErrorCode    ierr;
31461683a169SBarry Smith   const PetscScalar *array;
31471683a169SBarry Smith   PetscScalar       *v_colwise;
3148d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
3149d77f618aSHong Zhang 
31508baccfbdSHong Zhang   PetscFunctionBegin;
3151d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
31521683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&array);CHKERRQ(ierr);
3153d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3154d77f618aSHong Zhang   k = 0;
3155d77f618aSHong Zhang   for (j=0; j<N; j++) {
3156d77f618aSHong Zhang     cols[j] = j;
3157d77f618aSHong Zhang     for (i=0; i<M; i++) {
3158d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
3159d77f618aSHong Zhang     }
3160d77f618aSHong Zhang   }
3161d77f618aSHong Zhang   for (i=0; i<M; i++) {
3162d77f618aSHong Zhang     rows[i] = i;
3163d77f618aSHong Zhang   }
31641683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&array);CHKERRQ(ierr);
3165d77f618aSHong Zhang 
3166d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
3167d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
3168d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
3169d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
3170d77f618aSHong Zhang 
3171d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
3172d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
3173d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3174d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3175d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
3176d77f618aSHong Zhang 
3177511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
317828be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
3179d77f618aSHong Zhang   } else {
3180d77f618aSHong Zhang     *newmat = mat_elemental;
3181d77f618aSHong Zhang   }
31828baccfbdSHong Zhang   PetscFunctionReturn(0);
31838baccfbdSHong Zhang }
318465b80a83SHong Zhang #endif
31858baccfbdSHong Zhang 
318617359960SJose E. Roman PetscErrorCode  MatDenseSetLDA_SeqDense(Mat B,PetscInt lda)
31871b807ce4Svictorle {
31881b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
31897422da62SJose E. Roman   PetscBool    data;
319021a2c019SBarry Smith 
31911b807ce4Svictorle   PetscFunctionBegin;
31927422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
31937422da62SJose 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");
3194e32f2f54SBarry 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);
31951b807ce4Svictorle   b->lda = lda;
31961b807ce4Svictorle   PetscFunctionReturn(0);
31971b807ce4Svictorle }
31981b807ce4Svictorle 
3199d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
3200d528f656SJakub Kruzik {
3201d528f656SJakub Kruzik   PetscErrorCode ierr;
3202d528f656SJakub Kruzik   PetscMPIInt    size;
3203d528f656SJakub Kruzik 
3204d528f656SJakub Kruzik   PetscFunctionBegin;
3205ffc4695bSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr);
3206d528f656SJakub Kruzik   if (size == 1) {
3207d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
3208d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
3209d528f656SJakub Kruzik     } else {
3210d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
3211d528f656SJakub Kruzik     }
3212d528f656SJakub Kruzik   } else {
3213d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
3214d528f656SJakub Kruzik   }
3215d528f656SJakub Kruzik   PetscFunctionReturn(0);
3216d528f656SJakub Kruzik }
3217d528f656SJakub Kruzik 
32186947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
32196947451fSStefano Zampini {
32206947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32216947451fSStefano Zampini   PetscErrorCode ierr;
32226947451fSStefano Zampini 
32236947451fSStefano Zampini   PetscFunctionBegin;
32245ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
32255ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32266947451fSStefano Zampini   if (!a->cvec) {
32276947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
3228616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
32296947451fSStefano Zampini   }
32306947451fSStefano Zampini   a->vecinuse = col + 1;
32316947451fSStefano Zampini   ierr = MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
32326947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
32336947451fSStefano Zampini   *v   = a->cvec;
32346947451fSStefano Zampini   PetscFunctionReturn(0);
32356947451fSStefano Zampini }
32366947451fSStefano Zampini 
32376947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
32386947451fSStefano Zampini {
32396947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32406947451fSStefano Zampini   PetscErrorCode ierr;
32416947451fSStefano Zampini 
32426947451fSStefano Zampini   PetscFunctionBegin;
32435ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
32446947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
32456947451fSStefano Zampini   a->vecinuse = 0;
32466947451fSStefano Zampini   ierr = MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
32476947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
32486947451fSStefano Zampini   *v   = NULL;
32496947451fSStefano Zampini   PetscFunctionReturn(0);
32506947451fSStefano Zampini }
32516947451fSStefano Zampini 
32526947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
32536947451fSStefano Zampini {
32546947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32556947451fSStefano Zampini   PetscErrorCode ierr;
32566947451fSStefano Zampini 
32576947451fSStefano Zampini   PetscFunctionBegin;
32585ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
32595ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32606947451fSStefano Zampini   if (!a->cvec) {
32616947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
3262616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
32636947451fSStefano Zampini   }
32646947451fSStefano Zampini   a->vecinuse = col + 1;
32656947451fSStefano Zampini   ierr = MatDenseGetArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
32666947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
32676947451fSStefano Zampini   ierr = VecLockReadPush(a->cvec);CHKERRQ(ierr);
32686947451fSStefano Zampini   *v   = a->cvec;
32696947451fSStefano Zampini   PetscFunctionReturn(0);
32706947451fSStefano Zampini }
32716947451fSStefano Zampini 
32726947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
32736947451fSStefano Zampini {
32746947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32756947451fSStefano Zampini   PetscErrorCode ierr;
32766947451fSStefano Zampini 
32776947451fSStefano Zampini   PetscFunctionBegin;
32785ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
32796947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
32806947451fSStefano Zampini   a->vecinuse = 0;
32816947451fSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
32826947451fSStefano Zampini   ierr = VecLockReadPop(a->cvec);CHKERRQ(ierr);
32836947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
32846947451fSStefano Zampini   *v   = NULL;
32856947451fSStefano Zampini   PetscFunctionReturn(0);
32866947451fSStefano Zampini }
32876947451fSStefano Zampini 
32886947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
32896947451fSStefano Zampini {
32906947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32916947451fSStefano Zampini   PetscErrorCode ierr;
32926947451fSStefano Zampini 
32936947451fSStefano Zampini   PetscFunctionBegin;
32945ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
32955ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32966947451fSStefano Zampini   if (!a->cvec) {
32976947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
3298616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
32996947451fSStefano Zampini   }
33006947451fSStefano Zampini   a->vecinuse = col + 1;
33016947451fSStefano Zampini   ierr = MatDenseGetArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
33026947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
33036947451fSStefano Zampini   *v   = a->cvec;
33046947451fSStefano Zampini   PetscFunctionReturn(0);
33056947451fSStefano Zampini }
33066947451fSStefano Zampini 
33076947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
33086947451fSStefano Zampini {
33096947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
33106947451fSStefano Zampini   PetscErrorCode ierr;
33116947451fSStefano Zampini 
33126947451fSStefano Zampini   PetscFunctionBegin;
33135ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
33146947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
33156947451fSStefano Zampini   a->vecinuse = 0;
33166947451fSStefano Zampini   ierr = MatDenseRestoreArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
33176947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
33186947451fSStefano Zampini   *v   = NULL;
33196947451fSStefano Zampini   PetscFunctionReturn(0);
33206947451fSStefano Zampini }
33216947451fSStefano Zampini 
33225ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
33235ea7661aSPierre Jolivet {
33245ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
33255ea7661aSPierre Jolivet   PetscErrorCode ierr;
33265ea7661aSPierre Jolivet 
33275ea7661aSPierre Jolivet   PetscFunctionBegin;
33285ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
33295ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
33305ea7661aSPierre Jolivet   if (a->cmat && cend-cbegin != a->cmat->cmap->N) {
33315ea7661aSPierre Jolivet     ierr = MatDestroy(&a->cmat);CHKERRQ(ierr);
33325ea7661aSPierre Jolivet   }
33335ea7661aSPierre Jolivet   if (!a->cmat) {
3334616b8fbbSStefano 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);
3335616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cmat);CHKERRQ(ierr);
33365ea7661aSPierre Jolivet   } else {
3337616b8fbbSStefano Zampini     ierr = MatDensePlaceArray(a->cmat,a->v + (size_t)cbegin * (size_t)a->lda);CHKERRQ(ierr);
33385ea7661aSPierre Jolivet   }
3339616b8fbbSStefano Zampini   ierr = MatDenseSetLDA(a->cmat,a->lda);CHKERRQ(ierr);
33405ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
33415ea7661aSPierre Jolivet   *v = a->cmat;
33425ea7661aSPierre Jolivet   PetscFunctionReturn(0);
33435ea7661aSPierre Jolivet }
33445ea7661aSPierre Jolivet 
33455ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A,Mat *v)
33465ea7661aSPierre Jolivet {
33475ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
33485ea7661aSPierre Jolivet   PetscErrorCode ierr;
33495ea7661aSPierre Jolivet 
33505ea7661aSPierre Jolivet   PetscFunctionBegin;
33515ea7661aSPierre Jolivet   if (!a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetSubMatrix() first");
33525ea7661aSPierre Jolivet   if (!a->cmat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column matrix");
3353616b8fbbSStefano Zampini   if (*v != a->cmat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not the matrix obtained from MatDenseGetSubMatrix()");
33545ea7661aSPierre Jolivet   a->matinuse = 0;
33555ea7661aSPierre Jolivet   ierr = MatDenseResetArray(a->cmat);CHKERRQ(ierr);
33565ea7661aSPierre Jolivet   *v   = NULL;
33575ea7661aSPierre Jolivet   PetscFunctionReturn(0);
33585ea7661aSPierre Jolivet }
33595ea7661aSPierre Jolivet 
33600bad9183SKris Buschelman /*MC
3361fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
33620bad9183SKris Buschelman 
33630bad9183SKris Buschelman    Options Database Keys:
33640bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
33650bad9183SKris Buschelman 
33660bad9183SKris Buschelman   Level: beginner
33670bad9183SKris Buschelman 
336889665df3SBarry Smith .seealso: MatCreateSeqDense()
336989665df3SBarry Smith 
33700bad9183SKris Buschelman M*/
3371ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
3372273d9f13SBarry Smith {
3373273d9f13SBarry Smith   Mat_SeqDense   *b;
3374dfbe8321SBarry Smith   PetscErrorCode ierr;
33757c334f02SBarry Smith   PetscMPIInt    size;
3376273d9f13SBarry Smith 
3377273d9f13SBarry Smith   PetscFunctionBegin;
3378ffc4695bSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRMPI(ierr);
3379e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
338055659b69SBarry Smith 
3381b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
3382549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
338344cd7ae7SLois Curfman McInnes   B->data = (void*)b;
338418f449edSLois Curfman McInnes 
3385273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
33864e220ebcSLois Curfman McInnes 
33874905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)B,"MatQRFactor_C",MatQRFactor_SeqDense);CHKERRQ(ierr);
33884905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)B,"MatQRFactorNumeric_C",MatQRFactorNumeric_SeqDense);CHKERRQ(ierr);
33894905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)B,"MatQRFactorSymbolic_C",MatQRFactorSymbolic_SeqDense);CHKERRQ(ierr);
339049a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
3391ad16ce7aSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseSetLDA_C",MatDenseSetLDA_SeqDense);CHKERRQ(ierr);
3392bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
33938572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
3394d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
3395d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
3396d5ea218eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseReplaceArray_C",MatDenseReplaceArray_SeqDense);CHKERRQ(ierr);
33978572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
3398715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
33996947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayWrite_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
34006947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayWrite_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
3401bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
34028baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
34038baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
34048baccfbdSHong Zhang #endif
3405d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
3406d24d4204SJose E. Roman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_scalapack_C",MatConvert_Dense_ScaLAPACK);CHKERRQ(ierr);
3407d24d4204SJose E. Roman #endif
34082bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
34092bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA);CHKERRQ(ierr);
34104222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
34114222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
3412637a0070SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
34132bf066beSStefano Zampini #endif
3414bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
34154222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
34164222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
34174222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
34184222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
341996e6d5c4SRichard Tran Mills 
3420af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
3421af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
34226947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVec_C",MatDenseGetColumnVec_SeqDense);CHKERRQ(ierr);
34236947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVec_C",MatDenseRestoreColumnVec_SeqDense);CHKERRQ(ierr);
34246947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecRead_C",MatDenseGetColumnVecRead_SeqDense);CHKERRQ(ierr);
34256947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecRead_C",MatDenseRestoreColumnVecRead_SeqDense);CHKERRQ(ierr);
34266947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecWrite_C",MatDenseGetColumnVecWrite_SeqDense);CHKERRQ(ierr);
34276947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecWrite_C",MatDenseRestoreColumnVecWrite_SeqDense);CHKERRQ(ierr);
34285ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetSubMatrix_C",MatDenseGetSubMatrix_SeqDense);CHKERRQ(ierr);
34295ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreSubMatrix_C",MatDenseRestoreSubMatrix_SeqDense);CHKERRQ(ierr);
343017667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
34313a40ed3dSBarry Smith   PetscFunctionReturn(0);
3432289bc588SBarry Smith }
343386aefd0dSHong Zhang 
343486aefd0dSHong Zhang /*@C
3435af53bab2SHong 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.
343686aefd0dSHong Zhang 
343786aefd0dSHong Zhang    Not Collective
343886aefd0dSHong Zhang 
34395ea7661aSPierre Jolivet    Input Parameters:
344086aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
344186aefd0dSHong Zhang -  col - column index
344286aefd0dSHong Zhang 
344386aefd0dSHong Zhang    Output Parameter:
344486aefd0dSHong Zhang .  vals - pointer to the data
344586aefd0dSHong Zhang 
344686aefd0dSHong Zhang    Level: intermediate
344786aefd0dSHong Zhang 
344886aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
344986aefd0dSHong Zhang @*/
345086aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
345186aefd0dSHong Zhang {
345286aefd0dSHong Zhang   PetscErrorCode ierr;
345386aefd0dSHong Zhang 
345486aefd0dSHong Zhang   PetscFunctionBegin;
3455d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3456d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3457d5ea218eSStefano Zampini   PetscValidPointer(vals,3);
345886aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
345986aefd0dSHong Zhang   PetscFunctionReturn(0);
346086aefd0dSHong Zhang }
346186aefd0dSHong Zhang 
346286aefd0dSHong Zhang /*@C
346386aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
346486aefd0dSHong Zhang 
346586aefd0dSHong Zhang    Not Collective
346686aefd0dSHong Zhang 
346786aefd0dSHong Zhang    Input Parameter:
346886aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
346986aefd0dSHong Zhang 
347086aefd0dSHong Zhang    Output Parameter:
347186aefd0dSHong Zhang .  vals - pointer to the data
347286aefd0dSHong Zhang 
347386aefd0dSHong Zhang    Level: intermediate
347486aefd0dSHong Zhang 
347586aefd0dSHong Zhang .seealso: MatDenseGetColumn()
347686aefd0dSHong Zhang @*/
347786aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
347886aefd0dSHong Zhang {
347986aefd0dSHong Zhang   PetscErrorCode ierr;
348086aefd0dSHong Zhang 
348186aefd0dSHong Zhang   PetscFunctionBegin;
3482d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3483d5ea218eSStefano Zampini   PetscValidPointer(vals,2);
348486aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
348586aefd0dSHong Zhang   PetscFunctionReturn(0);
348686aefd0dSHong Zhang }
34876947451fSStefano Zampini 
34886947451fSStefano Zampini /*@C
34896947451fSStefano Zampini    MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec.
34906947451fSStefano Zampini 
34916947451fSStefano Zampini    Collective
34926947451fSStefano Zampini 
34935ea7661aSPierre Jolivet    Input Parameters:
34946947451fSStefano Zampini +  mat - the Mat object
34956947451fSStefano Zampini -  col - the column index
34966947451fSStefano Zampini 
34976947451fSStefano Zampini    Output Parameter:
34986947451fSStefano Zampini .  v - the vector
34996947451fSStefano Zampini 
35006947451fSStefano Zampini    Notes:
35016947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed.
35026947451fSStefano Zampini      Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access.
35036947451fSStefano Zampini 
35046947451fSStefano Zampini    Level: intermediate
35056947451fSStefano Zampini 
35066947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
35076947451fSStefano Zampini @*/
35086947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec(Mat A,PetscInt col,Vec *v)
35096947451fSStefano Zampini {
35106947451fSStefano Zampini   PetscErrorCode ierr;
35116947451fSStefano Zampini 
35126947451fSStefano Zampini   PetscFunctionBegin;
35136947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35146947451fSStefano Zampini   PetscValidType(A,1);
35156947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35166947451fSStefano Zampini   PetscValidPointer(v,3);
35176947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35186947451fSStefano 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);
35196947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
35206947451fSStefano Zampini   PetscFunctionReturn(0);
35216947451fSStefano Zampini }
35226947451fSStefano Zampini 
35236947451fSStefano Zampini /*@C
35246947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
35256947451fSStefano Zampini 
35266947451fSStefano Zampini    Collective
35276947451fSStefano Zampini 
35285ea7661aSPierre Jolivet    Input Parameters:
35296947451fSStefano Zampini +  mat - the Mat object
35306947451fSStefano Zampini .  col - the column index
35316947451fSStefano Zampini -  v - the Vec object
35326947451fSStefano Zampini 
35336947451fSStefano Zampini    Level: intermediate
35346947451fSStefano Zampini 
35356947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
35366947451fSStefano Zampini @*/
35376947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec *v)
35386947451fSStefano Zampini {
35396947451fSStefano Zampini   PetscErrorCode ierr;
35406947451fSStefano Zampini 
35416947451fSStefano Zampini   PetscFunctionBegin;
35426947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35436947451fSStefano Zampini   PetscValidType(A,1);
35446947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35456947451fSStefano Zampini   PetscValidPointer(v,3);
35466947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35476947451fSStefano 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);
35486947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
35496947451fSStefano Zampini   PetscFunctionReturn(0);
35506947451fSStefano Zampini }
35516947451fSStefano Zampini 
35526947451fSStefano Zampini /*@C
35536947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
35546947451fSStefano Zampini 
35556947451fSStefano Zampini    Collective
35566947451fSStefano Zampini 
35575ea7661aSPierre Jolivet    Input Parameters:
35586947451fSStefano Zampini +  mat - the Mat object
35596947451fSStefano Zampini -  col - the column index
35606947451fSStefano Zampini 
35616947451fSStefano Zampini    Output Parameter:
35626947451fSStefano Zampini .  v - the vector
35636947451fSStefano Zampini 
35646947451fSStefano Zampini    Notes:
35656947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
35666947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
35676947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
35686947451fSStefano Zampini 
35696947451fSStefano Zampini    Level: intermediate
35706947451fSStefano Zampini 
35716947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
35726947451fSStefano Zampini @*/
35736947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec *v)
35746947451fSStefano Zampini {
35756947451fSStefano Zampini   PetscErrorCode ierr;
35766947451fSStefano Zampini 
35776947451fSStefano Zampini   PetscFunctionBegin;
35786947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35796947451fSStefano Zampini   PetscValidType(A,1);
35806947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35816947451fSStefano Zampini   PetscValidPointer(v,3);
35826947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35836947451fSStefano 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);
35846947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
35856947451fSStefano Zampini   PetscFunctionReturn(0);
35866947451fSStefano Zampini }
35876947451fSStefano Zampini 
35886947451fSStefano Zampini /*@C
35896947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
35906947451fSStefano Zampini 
35916947451fSStefano Zampini    Collective
35926947451fSStefano Zampini 
35935ea7661aSPierre Jolivet    Input Parameters:
35946947451fSStefano Zampini +  mat - the Mat object
35956947451fSStefano Zampini .  col - the column index
35966947451fSStefano Zampini -  v - the Vec object
35976947451fSStefano Zampini 
35986947451fSStefano Zampini    Level: intermediate
35996947451fSStefano Zampini 
36006947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecWrite()
36016947451fSStefano Zampini @*/
36026947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec *v)
36036947451fSStefano Zampini {
36046947451fSStefano Zampini   PetscErrorCode ierr;
36056947451fSStefano Zampini 
36066947451fSStefano Zampini   PetscFunctionBegin;
36076947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36086947451fSStefano Zampini   PetscValidType(A,1);
36096947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
36106947451fSStefano Zampini   PetscValidPointer(v,3);
36116947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
36126947451fSStefano 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);
36136947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
36146947451fSStefano Zampini   PetscFunctionReturn(0);
36156947451fSStefano Zampini }
36166947451fSStefano Zampini 
36176947451fSStefano Zampini /*@C
36186947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
36196947451fSStefano Zampini 
36206947451fSStefano Zampini    Collective
36216947451fSStefano Zampini 
36225ea7661aSPierre Jolivet    Input Parameters:
36236947451fSStefano Zampini +  mat - the Mat object
36246947451fSStefano Zampini -  col - the column index
36256947451fSStefano Zampini 
36266947451fSStefano Zampini    Output Parameter:
36276947451fSStefano Zampini .  v - the vector
36286947451fSStefano Zampini 
36296947451fSStefano Zampini    Notes:
36306947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
36316947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
36326947451fSStefano Zampini 
36336947451fSStefano Zampini    Level: intermediate
36346947451fSStefano Zampini 
36356947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
36366947451fSStefano Zampini @*/
36376947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec *v)
36386947451fSStefano Zampini {
36396947451fSStefano Zampini   PetscErrorCode ierr;
36406947451fSStefano Zampini 
36416947451fSStefano Zampini   PetscFunctionBegin;
36426947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36436947451fSStefano Zampini   PetscValidType(A,1);
36446947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
36456947451fSStefano Zampini   PetscValidPointer(v,3);
36466947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
36476947451fSStefano 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);
36486947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
36496947451fSStefano Zampini   PetscFunctionReturn(0);
36506947451fSStefano Zampini }
36516947451fSStefano Zampini 
36526947451fSStefano Zampini /*@C
36536947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
36546947451fSStefano Zampini 
36556947451fSStefano Zampini    Collective
36566947451fSStefano Zampini 
36575ea7661aSPierre Jolivet    Input Parameters:
36586947451fSStefano Zampini +  mat - the Mat object
36596947451fSStefano Zampini .  col - the column index
36606947451fSStefano Zampini -  v - the Vec object
36616947451fSStefano Zampini 
36626947451fSStefano Zampini    Level: intermediate
36636947451fSStefano Zampini 
36646947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead()
36656947451fSStefano Zampini @*/
36666947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec *v)
36676947451fSStefano Zampini {
36686947451fSStefano Zampini   PetscErrorCode ierr;
36696947451fSStefano Zampini 
36706947451fSStefano Zampini   PetscFunctionBegin;
36716947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36726947451fSStefano Zampini   PetscValidType(A,1);
36736947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
36746947451fSStefano Zampini   PetscValidPointer(v,3);
36756947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
36766947451fSStefano 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);
36776947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
36786947451fSStefano Zampini   PetscFunctionReturn(0);
36796947451fSStefano Zampini }
36805ea7661aSPierre Jolivet 
36815ea7661aSPierre Jolivet /*@C
36825ea7661aSPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of columns of a dense matrix, represented as a Mat.
36835ea7661aSPierre Jolivet 
36845ea7661aSPierre Jolivet    Collective
36855ea7661aSPierre Jolivet 
36865ea7661aSPierre Jolivet    Input Parameters:
36875ea7661aSPierre Jolivet +  mat - the Mat object
36885ea7661aSPierre Jolivet .  cbegin - the first index in the block
36895ea7661aSPierre Jolivet -  cend - the last index in the block
36905ea7661aSPierre Jolivet 
36915ea7661aSPierre Jolivet    Output Parameter:
36925ea7661aSPierre Jolivet .  v - the matrix
36935ea7661aSPierre Jolivet 
36945ea7661aSPierre Jolivet    Notes:
36955ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
36965ea7661aSPierre Jolivet 
36975ea7661aSPierre Jolivet    Level: intermediate
36985ea7661aSPierre Jolivet 
36995ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseRestoreSubMatrix()
37005ea7661aSPierre Jolivet @*/
37015ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
37025ea7661aSPierre Jolivet {
37035ea7661aSPierre Jolivet   PetscErrorCode ierr;
37045ea7661aSPierre Jolivet 
37055ea7661aSPierre Jolivet   PetscFunctionBegin;
37065ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
37075ea7661aSPierre Jolivet   PetscValidType(A,1);
37085ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cbegin,2);
37095ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cend,3);
37105ea7661aSPierre Jolivet   PetscValidPointer(v,4);
37115ea7661aSPierre Jolivet   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
37125ea7661aSPierre 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);
3713616b8fbbSStefano 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);
37145ea7661aSPierre Jolivet   ierr = PetscUseMethod(A,"MatDenseGetSubMatrix_C",(Mat,PetscInt,PetscInt,Mat*),(A,cbegin,cend,v));CHKERRQ(ierr);
37155ea7661aSPierre Jolivet   PetscFunctionReturn(0);
37165ea7661aSPierre Jolivet }
37175ea7661aSPierre Jolivet 
37185ea7661aSPierre Jolivet /*@C
37195ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
37205ea7661aSPierre Jolivet 
37215ea7661aSPierre Jolivet    Collective
37225ea7661aSPierre Jolivet 
37235ea7661aSPierre Jolivet    Input Parameters:
37245ea7661aSPierre Jolivet +  mat - the Mat object
37255ea7661aSPierre Jolivet -  v - the Mat object
37265ea7661aSPierre Jolivet 
37275ea7661aSPierre Jolivet    Level: intermediate
37285ea7661aSPierre Jolivet 
37295ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseGetSubMatrix()
37305ea7661aSPierre Jolivet @*/
37315ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix(Mat A,Mat *v)
37325ea7661aSPierre Jolivet {
37335ea7661aSPierre Jolivet   PetscErrorCode ierr;
37345ea7661aSPierre Jolivet 
37355ea7661aSPierre Jolivet   PetscFunctionBegin;
37365ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
37375ea7661aSPierre Jolivet   PetscValidType(A,1);
37385ea7661aSPierre Jolivet   PetscValidPointer(v,2);
37395ea7661aSPierre Jolivet   ierr = PetscUseMethod(A,"MatDenseRestoreSubMatrix_C",(Mat,Mat*),(A,v));CHKERRQ(ierr);
37405ea7661aSPierre Jolivet   PetscFunctionReturn(0);
37415ea7661aSPierre Jolivet }
3742