xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 66e17bc34c6358e26731cd86c8afc040b40d70c0)
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 
4414396437dSToby 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;
4444396437dSToby Isaac   PetscBLASInt    info;
4456849ba73SBarry Smith   PetscErrorCode  ierr;
44667e560aaSBarry Smith 
4473a40ed3dSBarry Smith   PetscFunctionBegin;
44800121966SStefano Zampini   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4494396437dSToby 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);
4534396437dSToby Isaac   PetscFunctionReturn(0);
4544396437dSToby Isaac }
4554396437dSToby Isaac 
4564396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat);
4574396437dSToby Isaac 
4584396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt xlda, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
4594396437dSToby Isaac {
4604396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4614396437dSToby Isaac   PetscBLASInt    info;
4624396437dSToby Isaac   PetscErrorCode  ierr;
4634396437dSToby Isaac 
4644396437dSToby Isaac   PetscFunctionBegin;
465a49dc2a2SStefano Zampini   if (A->spd) {
4664396437dSToby 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");
4714396437dSToby 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) {
4744396437dSToby 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");
4794396437dSToby 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);
4884396437dSToby Isaac   PetscFunctionReturn(0);
4894396437dSToby Isaac }
49085e2c93fSHong Zhang 
4914396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt xlda, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
4924396437dSToby Isaac {
4934396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4944396437dSToby Isaac   PetscBLASInt    info;
4954396437dSToby Isaac   char            trans;
4964396437dSToby Isaac   PetscErrorCode  ierr;
4974396437dSToby Isaac 
4984396437dSToby 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 
5214396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt xlda, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
5224905a7bcSToby Isaac {
5234396437dSToby Isaac   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
5244396437dSToby Isaac   PetscBLASInt      info;
5254905a7bcSToby Isaac   PetscErrorCode    ierr;
5264396437dSToby Isaac 
5274396437dSToby Isaac   PetscFunctionBegin;
5284396437dSToby Isaac   if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
5294396437dSToby Isaac     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5304396437dSToby Isaac     PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "T", "N", &m,&nrhs,mat->v,&mat->lda,x,&xlda,&info));
5314396437dSToby Isaac     ierr = PetscFPTrapPop();CHKERRQ(ierr);
5324396437dSToby Isaac     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve");
5334396437dSToby Isaac     if (PetscDefined(USE_COMPLEX)) {ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);}
5344396437dSToby Isaac     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5354396437dSToby Isaac     PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", "N", &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&xlda,mat->fwork,&mat->lfwork,&info));
5364396437dSToby Isaac     ierr = PetscFPTrapPop();CHKERRQ(ierr);
5374396437dSToby Isaac     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform");
5384396437dSToby Isaac     if (PetscDefined(USE_COMPLEX)) {ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);}
5394396437dSToby Isaac   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"QR factored matrix cannot be used for transpose solve");
5404396437dSToby Isaac   ierr = PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank)));CHKERRQ(ierr);
5414396437dSToby Isaac   PetscFunctionReturn(0);
5424396437dSToby Isaac }
5434396437dSToby Isaac 
5444396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
5454396437dSToby Isaac {
5464396437dSToby Isaac   Mat_SeqDense      *mat = (Mat_SeqDense *) A->data;
5474905a7bcSToby Isaac   PetscScalar       *y;
5484905a7bcSToby Isaac   PetscBLASInt      m=0, k=0;
5494396437dSToby 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) {
5554396437dSToby Isaac     ierr = VecCopy(xx, mat->qrrhs);CHKERRQ(ierr);
5564396437dSToby Isaac     ierr = VecGetArray(mat->qrrhs,&y);CHKERRQ(ierr);
5574905a7bcSToby Isaac   } else {
5584396437dSToby Isaac     ierr = VecCopy(xx, yy);CHKERRQ(ierr);
5594905a7bcSToby Isaac     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
5604905a7bcSToby Isaac   }
5614396437dSToby Isaac   *_y = y;
5624396437dSToby Isaac   *_k = k;
5634396437dSToby Isaac   *_m = m;
5644396437dSToby Isaac   PetscFunctionReturn(0);
5654396437dSToby Isaac }
5664396437dSToby Isaac 
5674396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
5684396437dSToby Isaac {
5694396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
57042e9364cSSatish Balay   PetscScalar    *y = NULL;
5714396437dSToby Isaac   PetscBLASInt   m, k;
5724396437dSToby Isaac   PetscErrorCode ierr;
5734396437dSToby Isaac 
5744396437dSToby Isaac   PetscFunctionBegin;
5754396437dSToby Isaac   y   = *_y;
5764396437dSToby Isaac   *_y = NULL;
5774396437dSToby Isaac   k   = *_k;
5784396437dSToby 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);
5844396437dSToby 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 
5914396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy)
5924396437dSToby Isaac {
59342e9364cSSatish Balay   PetscScalar    *y = NULL;
59442e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
5954396437dSToby Isaac   PetscErrorCode ierr;
5964396437dSToby Isaac 
5974396437dSToby Isaac   PetscFunctionBegin;
5984396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
5994396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE);CHKERRQ(ierr);
6004396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6014396437dSToby Isaac   PetscFunctionReturn(0);
6024396437dSToby Isaac }
6034396437dSToby Isaac 
6044396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy)
6054396437dSToby Isaac {
60642e9364cSSatish Balay   PetscScalar    *y = NULL;
60742e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
6084396437dSToby Isaac   PetscErrorCode ierr;
6094396437dSToby Isaac 
6104396437dSToby Isaac   PetscFunctionBegin;
6114396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6124396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE);CHKERRQ(ierr);
6134396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6144396437dSToby Isaac   PetscFunctionReturn(0);
6154396437dSToby Isaac }
6164396437dSToby Isaac 
6174396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
6184396437dSToby Isaac {
619e54beecaSStefano Zampini   PetscScalar    *y = NULL;
620e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6214396437dSToby Isaac   PetscErrorCode ierr;
6224396437dSToby Isaac 
6234396437dSToby Isaac   PetscFunctionBegin;
6244396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6254396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE);CHKERRQ(ierr);
6264396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6274396437dSToby Isaac   PetscFunctionReturn(0);
6284396437dSToby Isaac }
6294396437dSToby Isaac 
6304396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
6314396437dSToby Isaac {
632e54beecaSStefano Zampini   PetscScalar    *y = NULL;
633e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6344396437dSToby Isaac   PetscErrorCode ierr;
6354396437dSToby Isaac 
6364396437dSToby Isaac   PetscFunctionBegin;
6374396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6384396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE);CHKERRQ(ierr);
6394396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6404396437dSToby Isaac   PetscFunctionReturn(0);
6414396437dSToby Isaac }
6424396437dSToby Isaac 
6434396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy)
6444396437dSToby Isaac {
645e54beecaSStefano Zampini   PetscScalar    *y = NULL;
646e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6474396437dSToby Isaac   PetscErrorCode ierr;
6484396437dSToby Isaac 
6494396437dSToby Isaac   PetscFunctionBegin;
6504396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6514396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k);CHKERRQ(ierr);
6524396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6534396437dSToby Isaac   PetscFunctionReturn(0);
6544396437dSToby Isaac }
6554396437dSToby Isaac 
6564396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy)
6574396437dSToby Isaac {
65842e9364cSSatish Balay   PetscScalar    *y = NULL;
65942e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
6604396437dSToby Isaac   PetscErrorCode ierr;
6614396437dSToby Isaac 
6624396437dSToby Isaac   PetscFunctionBegin;
6634396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6644396437dSToby Isaac   ierr = MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k);CHKERRQ(ierr);
6654396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6664396437dSToby Isaac   PetscFunctionReturn(0);
6674396437dSToby Isaac }
6684396437dSToby Isaac 
6694396437dSToby 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;
6734396437dSToby Isaac   PetscScalar       *y;
6744905a7bcSToby Isaac   PetscInt          n, _blda, _xlda;
6754396437dSToby Isaac   PetscBLASInt      nrhs=0,m=0,k=0,blda=0,xlda=0,ylda=0;
6764905a7bcSToby Isaac 
6774905a7bcSToby Isaac   PetscFunctionBegin;
67837b8ee88SJose E. Roman   *_ylda=0; *_m=0; *_nrhs=0; *_k=0;
6794905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
6804905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
6814905a7bcSToby Isaac   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
6824905a7bcSToby Isaac   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
6834905a7bcSToby Isaac   ierr = MatDenseGetLDA(B,&_blda);CHKERRQ(ierr);
6844905a7bcSToby Isaac   ierr = PetscBLASIntCast(_blda, &blda);CHKERRQ(ierr);
6854905a7bcSToby Isaac   ierr = MatDenseGetLDA(X,&_xlda);CHKERRQ(ierr);
6864905a7bcSToby Isaac   ierr = PetscBLASIntCast(_xlda, &xlda);CHKERRQ(ierr);
6874905a7bcSToby Isaac   if (xlda < m) {
6884396437dSToby Isaac     ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
6894396437dSToby Isaac     ierr = PetscMalloc1(nrhs * m, &y);CHKERRQ(ierr);
6904905a7bcSToby Isaac     if (blda == m) {
6914396437dSToby Isaac       ierr = PetscArraycpy(y,b,blda*nrhs);CHKERRQ(ierr);
6924905a7bcSToby Isaac     } else {
6934905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
6944396437dSToby Isaac         ierr = PetscArraycpy(&y[j*m],&b[j*blda],m);CHKERRQ(ierr);
6954905a7bcSToby Isaac       }
6964905a7bcSToby Isaac     }
6974396437dSToby Isaac     ylda = m;
6984396437dSToby Isaac     ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
6994905a7bcSToby Isaac   } else {
7004905a7bcSToby Isaac     if (blda == xlda) {
7014396437dSToby Isaac       ierr = MatCopy(B, X, SAME_NONZERO_PATTERN);CHKERRQ(ierr);
7024396437dSToby Isaac       ierr = MatDenseGetArray(X,&y);CHKERRQ(ierr);
7034905a7bcSToby Isaac     } else {
7044396437dSToby Isaac       ierr = MatDenseGetArray(X,&y);CHKERRQ(ierr);
7054396437dSToby Isaac       ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
7064905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
7074396437dSToby Isaac         ierr = PetscArraycpy(&y[j*xlda],&b[j*blda],m);CHKERRQ(ierr);
7084905a7bcSToby Isaac       }
7094396437dSToby Isaac       ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
7104905a7bcSToby Isaac     }
7114396437dSToby Isaac     ylda = xlda;
7124905a7bcSToby Isaac   }
7134396437dSToby Isaac   *_y    = y;
7144396437dSToby Isaac   *_ylda = ylda;
7154396437dSToby Isaac   *_k    = k;
7164396437dSToby Isaac   *_m    = m;
7174396437dSToby Isaac   *_nrhs = nrhs;
7184396437dSToby Isaac   PetscFunctionReturn(0);
7194396437dSToby Isaac }
7204396437dSToby Isaac 
7214396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ylda, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
7224396437dSToby Isaac {
7234396437dSToby Isaac   PetscScalar       *y;
7244396437dSToby Isaac   PetscInt          _xlda;
7254396437dSToby Isaac   PetscBLASInt      k,ylda,nrhs,xlda=0;
7264396437dSToby Isaac   PetscErrorCode    ierr;
7274396437dSToby Isaac 
7284396437dSToby Isaac   PetscFunctionBegin;
7294396437dSToby Isaac   y    = *_y;
7304396437dSToby Isaac   *_y  = NULL;
7314396437dSToby Isaac   k    = *_k;
7324396437dSToby Isaac   ylda = *_ylda;
7334396437dSToby Isaac   nrhs = *_nrhs;
7344396437dSToby Isaac   ierr = MatDenseGetLDA(X,&_xlda);CHKERRQ(ierr);
7354396437dSToby Isaac   ierr = PetscBLASIntCast(_xlda, &xlda);CHKERRQ(ierr);
7364396437dSToby Isaac   if (xlda != ylda) {
7374905a7bcSToby Isaac     PetscScalar *xv;
7384905a7bcSToby Isaac     ierr = MatDenseGetArray(X,&xv);CHKERRQ(ierr);
7394905a7bcSToby Isaac     for (PetscInt j = 0; j < nrhs; j++) {
7404396437dSToby Isaac       ierr = PetscArraycpy(&xv[j*xlda],&y[j*ylda],k);CHKERRQ(ierr);
7414905a7bcSToby Isaac     }
7424905a7bcSToby Isaac     ierr = MatDenseRestoreArray(X,&xv);CHKERRQ(ierr);
7434396437dSToby Isaac     ierr = PetscFree(y);CHKERRQ(ierr);
7444905a7bcSToby Isaac   } else {
7454396437dSToby Isaac     ierr = MatDenseRestoreArray(X,&y);CHKERRQ(ierr);
7464905a7bcSToby Isaac   }
74785e2c93fSHong Zhang   PetscFunctionReturn(0);
74885e2c93fSHong Zhang }
74985e2c93fSHong Zhang 
7504396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X)
7514396437dSToby Isaac {
7524396437dSToby Isaac   PetscScalar    *y;
7534396437dSToby Isaac   PetscBLASInt   m, k, ylda, nrhs;
7544396437dSToby Isaac   PetscErrorCode ierr;
7554396437dSToby Isaac 
7564396437dSToby Isaac   PetscFunctionBegin;
7574396437dSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
7584396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_LU(A, y, ylda, m, nrhs, k, PETSC_FALSE);CHKERRQ(ierr);
7594396437dSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
7604396437dSToby Isaac   PetscFunctionReturn(0);
7614396437dSToby Isaac }
7624396437dSToby Isaac 
7634396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X)
7644396437dSToby Isaac {
7654396437dSToby Isaac   PetscScalar    *y;
7664396437dSToby Isaac   PetscBLASInt   m, k, ylda, nrhs;
7674396437dSToby Isaac   PetscErrorCode ierr;
7684396437dSToby Isaac 
7694396437dSToby Isaac   PetscFunctionBegin;
7704396437dSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
7714396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_LU(A, y, ylda, m, nrhs, k, PETSC_TRUE);CHKERRQ(ierr);
7724396437dSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
7734396437dSToby Isaac   PetscFunctionReturn(0);
7744396437dSToby Isaac }
7754396437dSToby Isaac 
7764396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X)
7774396437dSToby Isaac {
7784396437dSToby Isaac   PetscScalar    *y;
7794396437dSToby Isaac   PetscBLASInt   m, k, ylda, nrhs;
7804396437dSToby Isaac   PetscErrorCode ierr;
7814396437dSToby Isaac 
7824396437dSToby Isaac   PetscFunctionBegin;
7834396437dSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
7844396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_Cholesky(A, y, ylda, m, nrhs, k, PETSC_FALSE);CHKERRQ(ierr);
7854396437dSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
7864396437dSToby Isaac   PetscFunctionReturn(0);
7874396437dSToby Isaac }
7884396437dSToby Isaac 
7894396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X)
7904396437dSToby Isaac {
7914396437dSToby Isaac   PetscScalar    *y;
7924396437dSToby Isaac   PetscBLASInt   m, k, ylda, nrhs;
7934396437dSToby Isaac   PetscErrorCode ierr;
7944396437dSToby Isaac 
7954396437dSToby Isaac   PetscFunctionBegin;
7964396437dSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
7974396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_Cholesky(A, y, ylda, m, nrhs, k, PETSC_TRUE);CHKERRQ(ierr);
7984396437dSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
7994396437dSToby Isaac   PetscFunctionReturn(0);
8004396437dSToby Isaac }
8014396437dSToby Isaac 
8024396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X)
8034396437dSToby Isaac {
8044396437dSToby Isaac   PetscScalar    *y;
8054396437dSToby Isaac   PetscBLASInt   m, k, ylda, nrhs;
8064396437dSToby Isaac   PetscErrorCode ierr;
8074396437dSToby Isaac 
8084396437dSToby Isaac   PetscFunctionBegin;
8094396437dSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
8104396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_QR(A, y, ylda, m, nrhs, k);CHKERRQ(ierr);
8114396437dSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
8124396437dSToby Isaac   PetscFunctionReturn(0);
8134396437dSToby Isaac }
8144396437dSToby Isaac 
8154396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X)
8164396437dSToby Isaac {
8174396437dSToby Isaac   PetscScalar    *y;
8184396437dSToby Isaac   PetscBLASInt   m, k, ylda, nrhs;
8194396437dSToby Isaac   PetscErrorCode ierr;
8204396437dSToby Isaac 
8214396437dSToby Isaac   PetscFunctionBegin;
8224396437dSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
8234396437dSToby Isaac   ierr = MatSolveTranspose_SeqDense_Internal_QR(A, y, ylda, m, nrhs, k);CHKERRQ(ierr);
8244396437dSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ylda, &m, &nrhs, &k);CHKERRQ(ierr);
8254396437dSToby Isaac   PetscFunctionReturn(0);
8264396437dSToby Isaac }
8274396437dSToby Isaac 
82800121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
82900121966SStefano Zampini 
830db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
831db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
832db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
833ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
834db4efbfdSBarry Smith {
835db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
836db4efbfdSBarry Smith   PetscErrorCode ierr;
837db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
838db4efbfdSBarry Smith 
839db4efbfdSBarry Smith   PetscFunctionBegin;
840c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
841c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
842db4efbfdSBarry Smith   if (!mat->pivots) {
8438208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
8443bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
845db4efbfdSBarry Smith   }
846db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
8478e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
8488b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
8498e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
8508e57ea43SSatish Balay 
851e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
852e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
8538208b9aeSStefano Zampini 
8544396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
8554396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
8564396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8574396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
858d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
859db4efbfdSBarry Smith 
860f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
861f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
862f6224b95SHong Zhang 
863dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
864db4efbfdSBarry Smith   PetscFunctionReturn(0);
865db4efbfdSBarry Smith }
866db4efbfdSBarry Smith 
8674396437dSToby Isaac static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
8684396437dSToby Isaac {
8694396437dSToby Isaac   MatFactorInfo  info;
8704396437dSToby Isaac   PetscErrorCode ierr;
8714396437dSToby Isaac 
8724396437dSToby Isaac   PetscFunctionBegin;
8734396437dSToby Isaac   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
8744396437dSToby Isaac   ierr = (*fact->ops->lufactor)(fact,NULL,NULL,&info);CHKERRQ(ierr);
8754396437dSToby Isaac   PetscFunctionReturn(0);
8764396437dSToby Isaac }
8774396437dSToby Isaac 
8784396437dSToby Isaac PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
8794396437dSToby Isaac {
8804396437dSToby Isaac   PetscFunctionBegin;
8814396437dSToby Isaac   fact->preallocated           = PETSC_TRUE;
8824396437dSToby Isaac   fact->assembled              = PETSC_TRUE;
8834396437dSToby Isaac   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
8844396437dSToby Isaac   fact->ops->solve             = MatSolve_SeqDense_LU;
8854396437dSToby Isaac   fact->ops->matsolve          = MatMatSolve_SeqDense_LU;
8864396437dSToby Isaac   fact->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8874396437dSToby Isaac   PetscFunctionReturn(0);
8884396437dSToby Isaac }
8894396437dSToby Isaac 
890a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
891ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
892db4efbfdSBarry Smith {
893db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
894db4efbfdSBarry Smith   PetscErrorCode ierr;
895c5df96a5SBarry Smith   PetscBLASInt   info,n;
896db4efbfdSBarry Smith 
897db4efbfdSBarry Smith   PetscFunctionBegin;
898c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
899db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
900a49dc2a2SStefano Zampini   if (A->spd) {
90100121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
9028b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
90300121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
904a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
905a49dc2a2SStefano Zampini   } else if (A->hermitian) {
906a49dc2a2SStefano Zampini     if (!mat->pivots) {
907a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
908a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
909a49dc2a2SStefano Zampini     }
910a49dc2a2SStefano Zampini     if (!mat->fwork) {
911a49dc2a2SStefano Zampini       PetscScalar dummy;
912a49dc2a2SStefano Zampini 
913a49dc2a2SStefano Zampini       mat->lfwork = -1;
91400121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
915a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
91600121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
917a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
918a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
919a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
920a49dc2a2SStefano Zampini     }
92100121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
922a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
92300121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
924a49dc2a2SStefano Zampini #endif
925a49dc2a2SStefano Zampini   } else { /* symmetric case */
926a49dc2a2SStefano Zampini     if (!mat->pivots) {
927a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
928a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
929a49dc2a2SStefano Zampini     }
930a49dc2a2SStefano Zampini     if (!mat->fwork) {
931a49dc2a2SStefano Zampini       PetscScalar dummy;
932a49dc2a2SStefano Zampini 
933a49dc2a2SStefano Zampini       mat->lfwork = -1;
93400121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
935a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
93600121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
937a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
938a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
939a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
940a49dc2a2SStefano Zampini     }
94100121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
942a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
94300121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
944a49dc2a2SStefano Zampini   }
945e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
9468208b9aeSStefano Zampini 
9474396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
9484396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
9494396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
9504396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
951d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
9522205254eSKarl Rupp 
953f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
954f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
955f6224b95SHong Zhang 
956eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
957db4efbfdSBarry Smith   PetscFunctionReturn(0);
958db4efbfdSBarry Smith }
959db4efbfdSBarry Smith 
9604396437dSToby Isaac static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
961db4efbfdSBarry Smith {
962db4efbfdSBarry Smith   PetscErrorCode ierr;
963db4efbfdSBarry Smith   MatFactorInfo  info;
964db4efbfdSBarry Smith 
965db4efbfdSBarry Smith   PetscFunctionBegin;
966db4efbfdSBarry Smith   info.fill = 1.0;
9672205254eSKarl Rupp 
968c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
969f4259b30SLisandro Dalcin   ierr = (*fact->ops->choleskyfactor)(fact,NULL,&info);CHKERRQ(ierr);
970db4efbfdSBarry Smith   PetscFunctionReturn(0);
971db4efbfdSBarry Smith }
972db4efbfdSBarry Smith 
973ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
974db4efbfdSBarry Smith {
975db4efbfdSBarry Smith   PetscFunctionBegin;
976c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9771bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
978719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
9794396437dSToby Isaac   fact->ops->solve                 = MatSolve_SeqDense_Cholesky;
9804396437dSToby Isaac   fact->ops->matsolve              = MatMatSolve_SeqDense_Cholesky;
9814396437dSToby Isaac   fact->ops->solvetranspose        = MatSolve_SeqDense_Cholesky;
982db4efbfdSBarry Smith   PetscFunctionReturn(0);
983db4efbfdSBarry Smith }
984db4efbfdSBarry Smith 
9854905a7bcSToby Isaac static PetscErrorCode MatQRFactor_SeqDense(Mat A,IS col,const MatFactorInfo *minfo)
9864905a7bcSToby Isaac {
9874905a7bcSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
9884905a7bcSToby Isaac   PetscErrorCode ierr;
9894905a7bcSToby Isaac   PetscBLASInt   n,m,info, min, max;
9904905a7bcSToby Isaac 
9914905a7bcSToby Isaac   PetscFunctionBegin;
9924905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
9934905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
9944396437dSToby Isaac   max = PetscMax(m, n);
9954396437dSToby Isaac   min = PetscMin(m, n);
9964905a7bcSToby Isaac   if (!mat->tau) {
9974396437dSToby Isaac     ierr = PetscMalloc1(min,&mat->tau);CHKERRQ(ierr);
9984396437dSToby Isaac     ierr = PetscLogObjectMemory((PetscObject)A,min*sizeof(PetscScalar));CHKERRQ(ierr);
9994396437dSToby Isaac   }
10004396437dSToby Isaac   if (!mat->pivots) {
10014396437dSToby Isaac     ierr = PetscMalloc1(m,&mat->pivots);CHKERRQ(ierr);
10024396437dSToby Isaac     ierr = PetscLogObjectMemory((PetscObject)A,m*sizeof(PetscScalar));CHKERRQ(ierr);
10034396437dSToby Isaac   }
10044396437dSToby Isaac   if (!mat->qrrhs) {
10054396437dSToby Isaac     ierr = MatCreateVecs(A, NULL, &(mat->qrrhs));CHKERRQ(ierr);
10064905a7bcSToby Isaac   }
10074905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
10084905a7bcSToby Isaac   if (!mat->fwork) {
10094905a7bcSToby Isaac     PetscScalar dummy;
10104905a7bcSToby Isaac 
10114905a7bcSToby Isaac     mat->lfwork = -1;
10124905a7bcSToby Isaac     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
10134905a7bcSToby Isaac     PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,&dummy,&mat->lfwork,&info));
10144905a7bcSToby Isaac     ierr = PetscFPTrapPop();CHKERRQ(ierr);
10154905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
10164905a7bcSToby Isaac     ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
10174905a7bcSToby Isaac     ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
10184905a7bcSToby Isaac   }
10194905a7bcSToby Isaac   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
10204905a7bcSToby Isaac   PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,mat->fwork,&mat->lfwork,&info));
10214905a7bcSToby Isaac   ierr = PetscFPTrapPop();CHKERRQ(ierr);
10224905a7bcSToby Isaac   if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to QR factorization");
10234905a7bcSToby 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
10244905a7bcSToby Isaac   mat->rank = min;
10254905a7bcSToby Isaac 
10264396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_QR;
10274396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_QR;
10284905a7bcSToby Isaac   A->factortype             = MAT_FACTOR_QR;
10294905a7bcSToby Isaac   if (m == n) {
10304396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
10314396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
10324905a7bcSToby Isaac   }
10334905a7bcSToby Isaac 
10344905a7bcSToby Isaac   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
10354905a7bcSToby Isaac   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
10364905a7bcSToby Isaac 
10374905a7bcSToby Isaac   ierr = PetscLogFlops(2.0*min*min*(max-min/3.0));CHKERRQ(ierr);
10384905a7bcSToby Isaac   PetscFunctionReturn(0);
10394905a7bcSToby Isaac }
10404905a7bcSToby Isaac 
10414905a7bcSToby Isaac static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
10424905a7bcSToby Isaac {
10434905a7bcSToby Isaac   PetscErrorCode ierr;
10444905a7bcSToby Isaac   MatFactorInfo  info;
10454905a7bcSToby Isaac 
10464905a7bcSToby Isaac   PetscFunctionBegin;
10474905a7bcSToby Isaac   info.fill = 1.0;
10484905a7bcSToby Isaac 
10494905a7bcSToby Isaac   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
10504905a7bcSToby Isaac   ierr = MatQRFactor_SeqDense(fact,NULL,&info);CHKERRQ(ierr);
10514905a7bcSToby Isaac   PetscFunctionReturn(0);
10524905a7bcSToby Isaac }
10534905a7bcSToby Isaac 
10544905a7bcSToby Isaac static PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
10554905a7bcSToby Isaac {
10564905a7bcSToby Isaac   PetscErrorCode ierr;
10574905a7bcSToby Isaac 
10584905a7bcSToby Isaac   PetscFunctionBegin;
10594905a7bcSToby Isaac   fact->assembled                  = PETSC_TRUE;
10604905a7bcSToby Isaac   fact->preallocated               = PETSC_TRUE;
10614396437dSToby Isaac   fact->ops->solve                 = MatSolve_SeqDense_QR;
10624396437dSToby Isaac   fact->ops->matsolve              = MatMatSolve_SeqDense_QR;
10634396437dSToby Isaac   if (A->cmap->n == A->rmap->n) {
10644396437dSToby Isaac     fact->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
10654396437dSToby Isaac     fact->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
10664396437dSToby Isaac   }
10674905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)fact,"MatQRFactorNumeric_C",MatQRFactorNumeric_SeqDense);CHKERRQ(ierr);
10684905a7bcSToby Isaac   PetscFunctionReturn(0);
10694905a7bcSToby Isaac }
10704905a7bcSToby Isaac 
10714905a7bcSToby Isaac 
1072ca15aa20SStefano Zampini /* uses LAPACK */
1073cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
1074db4efbfdSBarry Smith {
1075db4efbfdSBarry Smith   PetscErrorCode ierr;
1076db4efbfdSBarry Smith 
1077db4efbfdSBarry Smith   PetscFunctionBegin;
1078ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
1079db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1080ca15aa20SStefano Zampini   ierr = MatSetType(*fact,MATDENSE);CHKERRQ(ierr);
1081*66e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
10822a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
1083db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
10842a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
1085db4efbfdSBarry Smith   } else {
1086db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
1087db4efbfdSBarry Smith   }
1088d5f3da31SBarry Smith   (*fact)->factortype = ftype;
108900c67f3bSHong Zhang 
109000c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
109100c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
10924ac6704cSBarry Smith   ierr = PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_LU]);CHKERRQ(ierr);
10934ac6704cSBarry Smith   ierr = PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ILU]);CHKERRQ(ierr);
10944ac6704cSBarry Smith   ierr = PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]);CHKERRQ(ierr);
10954ac6704cSBarry Smith   ierr = PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ICC]);CHKERRQ(ierr);
1096db4efbfdSBarry Smith   PetscFunctionReturn(0);
1097db4efbfdSBarry Smith }
1098db4efbfdSBarry Smith 
1099289bc588SBarry Smith /* ------------------------------------------------------------------*/
1100e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
1101289bc588SBarry Smith {
1102c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1103d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
1104d9ca1df4SBarry Smith   const PetscScalar *b;
1105dfbe8321SBarry Smith   PetscErrorCode    ierr;
1106d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
110723fff9afSBarry Smith   PetscBLASInt      o = 1,bm = 0;
1108289bc588SBarry Smith 
11093a40ed3dSBarry Smith   PetscFunctionBegin;
1110ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1111c70f7ee4SJunchao Zhang   if (A->offloadmask == PETSC_OFFLOAD_GPU) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
1112ca15aa20SStefano Zampini #endif
1113422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
1114c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
1115289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
11163bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
11172dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
1118289bc588SBarry Smith   }
11191ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1120d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1121b965ef7fSBarry Smith   its  = its*lits;
1122e32f2f54SBarry 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);
1123289bc588SBarry Smith   while (its--) {
1124fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1125289bc588SBarry Smith       for (i=0; i<m; 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     }
1130fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1131289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
11323bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
113355a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1134289bc588SBarry Smith       }
1135289bc588SBarry Smith     }
1136289bc588SBarry Smith   }
1137d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
11381ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11393a40ed3dSBarry Smith   PetscFunctionReturn(0);
1140289bc588SBarry Smith }
1141289bc588SBarry Smith 
1142289bc588SBarry Smith /* -----------------------------------------------------------------*/
1143ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
1144289bc588SBarry Smith {
1145c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1146d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
1147d9ca1df4SBarry Smith   PetscScalar       *y;
1148dfbe8321SBarry Smith   PetscErrorCode    ierr;
11490805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
1150ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
11513a40ed3dSBarry Smith 
11523a40ed3dSBarry Smith   PetscFunctionBegin;
1153c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1154c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
1155d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11562bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
11575ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11585ac36cfcSBarry Smith     PetscBLASInt i;
11595ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
11605ac36cfcSBarry Smith   } else {
11618b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
11625ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
11635ac36cfcSBarry Smith   }
1164d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
11652bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
11663a40ed3dSBarry Smith   PetscFunctionReturn(0);
1167289bc588SBarry Smith }
1168800995b7SMatthew Knepley 
1169ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
1170289bc588SBarry Smith {
1171c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1172d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
1173dfbe8321SBarry Smith   PetscErrorCode    ierr;
11740805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
1175d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
11763a40ed3dSBarry Smith 
11773a40ed3dSBarry Smith   PetscFunctionBegin;
1178c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1179c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
1180d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11812bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
11825ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11835ac36cfcSBarry Smith     PetscBLASInt i;
11845ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
11855ac36cfcSBarry Smith   } else {
11868b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
11875ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
11885ac36cfcSBarry Smith   }
1189d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
11902bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
11913a40ed3dSBarry Smith   PetscFunctionReturn(0);
1192289bc588SBarry Smith }
11936ee01492SSatish Balay 
1194ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1195289bc588SBarry Smith {
1196c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1197d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1198d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
1199dfbe8321SBarry Smith   PetscErrorCode    ierr;
12000805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
12013a40ed3dSBarry Smith 
12023a40ed3dSBarry Smith   PetscFunctionBegin;
1203c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1204c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
120517b127eeSStefano Zampini   ierr = VecCopy(zz,yy);CHKERRQ(ierr);
1206d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
1207d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12081ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
12098b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
1210d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12111ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1212dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
12133a40ed3dSBarry Smith   PetscFunctionReturn(0);
1214289bc588SBarry Smith }
12156ee01492SSatish Balay 
1216ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1217289bc588SBarry Smith {
1218c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1219d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1220d9ca1df4SBarry Smith   PetscScalar       *y;
1221dfbe8321SBarry Smith   PetscErrorCode    ierr;
12220805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
122387828ca2SBarry Smith   PetscScalar       _DOne=1.0;
12243a40ed3dSBarry Smith 
12253a40ed3dSBarry Smith   PetscFunctionBegin;
1226c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1227c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
122817b127eeSStefano Zampini   ierr = VecCopy(zz,yy);CHKERRQ(ierr);
1229d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
1230d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12311ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
12328b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
1233d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12341ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1235dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
12363a40ed3dSBarry Smith   PetscFunctionReturn(0);
1237289bc588SBarry Smith }
1238289bc588SBarry Smith 
1239289bc588SBarry Smith /* -----------------------------------------------------------------*/
1240e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1241289bc588SBarry Smith {
1242c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
12436849ba73SBarry Smith   PetscErrorCode ierr;
124413f74950SBarry Smith   PetscInt       i;
124567e560aaSBarry Smith 
12463a40ed3dSBarry Smith   PetscFunctionBegin;
1247d0f46423SBarry Smith   *ncols = A->cmap->n;
1248289bc588SBarry Smith   if (cols) {
12493741e84bSPierre Jolivet     ierr = PetscMalloc1(A->cmap->n,cols);CHKERRQ(ierr);
1250d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
1251289bc588SBarry Smith   }
1252289bc588SBarry Smith   if (vals) {
1253ca15aa20SStefano Zampini     const PetscScalar *v;
1254ca15aa20SStefano Zampini 
1255ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
12563741e84bSPierre Jolivet     ierr = PetscMalloc1(A->cmap->n,vals);CHKERRQ(ierr);
1257ca15aa20SStefano Zampini     v   += row;
1258d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
1259ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1260289bc588SBarry Smith   }
12613a40ed3dSBarry Smith   PetscFunctionReturn(0);
1262289bc588SBarry Smith }
12636ee01492SSatish Balay 
1264e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1265289bc588SBarry Smith {
1266dfbe8321SBarry Smith   PetscErrorCode ierr;
12676e111a19SKarl Rupp 
1268606d414cSSatish Balay   PetscFunctionBegin;
1269cb4a9cd9SHong Zhang   if (ncols) *ncols = 0;
1270606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
1271606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
12723a40ed3dSBarry Smith   PetscFunctionReturn(0);
1273289bc588SBarry Smith }
1274289bc588SBarry Smith /* ----------------------------------------------------------------*/
1275e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
1276289bc588SBarry Smith {
1277c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
1278ca15aa20SStefano Zampini   PetscScalar      *av;
127913f74950SBarry Smith   PetscInt         i,j,idx=0;
1280ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1281c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1282ca15aa20SStefano Zampini #endif
1283ca15aa20SStefano Zampini   PetscErrorCode   ierr;
1284d6dfbf8fSBarry Smith 
12853a40ed3dSBarry Smith   PetscFunctionBegin;
1286ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&av);CHKERRQ(ierr);
1287289bc588SBarry Smith   if (!mat->roworiented) {
1288dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1289289bc588SBarry Smith       for (j=0; j<n; j++) {
1290cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
1291cf9c20a2SJed 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);
1292289bc588SBarry Smith         for (i=0; i<m; i++) {
1293cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
1294cf9c20a2SJed 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);
1295ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1296289bc588SBarry Smith         }
1297289bc588SBarry Smith       }
12983a40ed3dSBarry Smith     } else {
1299289bc588SBarry Smith       for (j=0; j<n; j++) {
1300cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
1301cf9c20a2SJed 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);
1302289bc588SBarry Smith         for (i=0; i<m; i++) {
1303cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
1304cf9c20a2SJed 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);
1305ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1306289bc588SBarry Smith         }
1307289bc588SBarry Smith       }
1308289bc588SBarry Smith     }
13093a40ed3dSBarry Smith   } else {
1310dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1311e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
1312cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
1313cf9c20a2SJed 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);
1314e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
1315cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
1316cf9c20a2SJed 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);
1317ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1318e8d4e0b9SBarry Smith         }
1319e8d4e0b9SBarry Smith       }
13203a40ed3dSBarry Smith     } else {
1321289bc588SBarry Smith       for (i=0; i<m; i++) {
1322cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
1323cf9c20a2SJed 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);
1324289bc588SBarry Smith         for (j=0; j<n; j++) {
1325cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
1326cf9c20a2SJed 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);
1327ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1328289bc588SBarry Smith         }
1329289bc588SBarry Smith       }
1330289bc588SBarry Smith     }
1331e8d4e0b9SBarry Smith   }
1332ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
1333ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1334c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
1335c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1336ca15aa20SStefano Zampini #endif
1337ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&av);CHKERRQ(ierr);
1338ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1339c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1340ca15aa20SStefano Zampini #endif
13413a40ed3dSBarry Smith   PetscFunctionReturn(0);
1342289bc588SBarry Smith }
1343e8d4e0b9SBarry Smith 
1344e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1345ae80bb75SLois Curfman McInnes {
1346ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1347ca15aa20SStefano Zampini   const PetscScalar *vv;
134813f74950SBarry Smith   PetscInt          i,j;
1349ca15aa20SStefano Zampini   PetscErrorCode    ierr;
1350ae80bb75SLois Curfman McInnes 
13513a40ed3dSBarry Smith   PetscFunctionBegin;
1352ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1353ae80bb75SLois Curfman McInnes   /* row-oriented output */
1354ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
135597e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1356e32f2f54SBarry 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);
1357ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
13586f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1359e32f2f54SBarry 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);
1360ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1361ae80bb75SLois Curfman McInnes     }
1362ae80bb75SLois Curfman McInnes   }
1363ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
13643a40ed3dSBarry Smith   PetscFunctionReturn(0);
1365ae80bb75SLois Curfman McInnes }
1366ae80bb75SLois Curfman McInnes 
1367289bc588SBarry Smith /* -----------------------------------------------------------------*/
1368289bc588SBarry Smith 
13698491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1370aabbc4fbSShri Abhyankar {
1371aabbc4fbSShri Abhyankar   PetscErrorCode    ierr;
13728491ab44SLisandro Dalcin   PetscBool         skipHeader;
13738491ab44SLisandro Dalcin   PetscViewerFormat format;
13748491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
13758491ab44SLisandro Dalcin   const PetscScalar *v;
13768491ab44SLisandro Dalcin   PetscScalar       *vwork;
1377aabbc4fbSShri Abhyankar 
1378aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13798491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
13808491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
13818491ab44SLisandro Dalcin   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
13828491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1383aabbc4fbSShri Abhyankar 
13848491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
13858491ab44SLisandro Dalcin 
13868491ab44SLisandro Dalcin   /* write matrix header */
13878491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
13888491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
13898491ab44SLisandro Dalcin   if (!skipHeader) {ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);}
13908491ab44SLisandro Dalcin 
13918491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
13928491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13938491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
13948491ab44SLisandro Dalcin     /* store row lengths for each row */
13958491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
13968491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
13978491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
13988491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13998491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
14008491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
14018491ab44SLisandro Dalcin         iwork[k] = j;
14028491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
14038491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
14048491ab44SLisandro Dalcin   }
14058491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
14068491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
14078491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
14088491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
14098491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
14108491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
14118491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
14128491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
14138491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
14148491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
14158491ab44SLisandro Dalcin   PetscFunctionReturn(0);
14168491ab44SLisandro Dalcin }
14178491ab44SLisandro Dalcin 
14188491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
14198491ab44SLisandro Dalcin {
14208491ab44SLisandro Dalcin   PetscErrorCode ierr;
14218491ab44SLisandro Dalcin   PetscBool      skipHeader;
14228491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
14238491ab44SLisandro Dalcin   PetscInt       rows,cols;
14248491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
14258491ab44SLisandro Dalcin 
14268491ab44SLisandro Dalcin   PetscFunctionBegin;
14278491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
14288491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
14298491ab44SLisandro Dalcin 
14308491ab44SLisandro Dalcin   if (!skipHeader) {
14318491ab44SLisandro Dalcin     ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
14328491ab44SLisandro Dalcin     if (header[0] != MAT_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
14338491ab44SLisandro Dalcin     M = header[1]; N = header[2];
14348491ab44SLisandro Dalcin     if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M);
14358491ab44SLisandro Dalcin     if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N);
14368491ab44SLisandro Dalcin     nz = header[3];
14378491ab44SLisandro Dalcin     if (nz != MATRIX_BINARY_FORMAT_DENSE && nz < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %D in file",nz);
1438aabbc4fbSShri Abhyankar   } else {
14398491ab44SLisandro Dalcin     ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
14408491ab44SLisandro 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");
14418491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1442e6324fbbSBarry Smith   }
1443aabbc4fbSShri Abhyankar 
14448491ab44SLisandro Dalcin   /* setup global sizes if not set */
14458491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
14468491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
14478491ab44SLisandro Dalcin   ierr = MatSetUp(mat);CHKERRQ(ierr);
14488491ab44SLisandro Dalcin   /* check if global sizes are correct */
14498491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
14508491ab44SLisandro 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);
1451aabbc4fbSShri Abhyankar 
14528491ab44SLisandro Dalcin   ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
14538491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
14548491ab44SLisandro Dalcin   ierr = MatDenseGetArray(mat,&v);CHKERRQ(ierr);
14558491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
14568491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
14578491ab44SLisandro Dalcin     PetscInt nnz = m*N;
14588491ab44SLisandro Dalcin     /* read in matrix values */
14598491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&vwork);CHKERRQ(ierr);
14608491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
14618491ab44SLisandro Dalcin     /* store values in column major order */
14628491ab44SLisandro Dalcin     for (j=0; j<N; j++)
14638491ab44SLisandro Dalcin       for (i=0; i<m; i++)
14648491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
14658491ab44SLisandro Dalcin     ierr = PetscFree(vwork);CHKERRQ(ierr);
14668491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14678491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14688491ab44SLisandro Dalcin     /* read in row lengths */
14698491ab44SLisandro Dalcin     ierr = PetscMalloc1(m,&rlens);CHKERRQ(ierr);
14708491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
14718491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
14728491ab44SLisandro Dalcin     /* read in column indices and values */
14738491ab44SLisandro Dalcin     ierr = PetscMalloc2(nnz,&icols,nnz,&vwork);CHKERRQ(ierr);
14748491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
14758491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
14768491ab44SLisandro Dalcin     /* store values in column major order */
14778491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
14788491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
14798491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
14808491ab44SLisandro Dalcin     ierr = PetscFree(rlens);CHKERRQ(ierr);
14818491ab44SLisandro Dalcin     ierr = PetscFree2(icols,vwork);CHKERRQ(ierr);
1482aabbc4fbSShri Abhyankar   }
14838491ab44SLisandro Dalcin   ierr = MatDenseRestoreArray(mat,&v);CHKERRQ(ierr);
14848491ab44SLisandro Dalcin   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14858491ab44SLisandro Dalcin   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1486aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1487aabbc4fbSShri Abhyankar }
1488aabbc4fbSShri Abhyankar 
1489eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1490eb91f321SVaclav Hapla {
1491eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1492eb91f321SVaclav Hapla   PetscErrorCode ierr;
1493eb91f321SVaclav Hapla 
1494eb91f321SVaclav Hapla   PetscFunctionBegin;
1495eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1496eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1497eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
1498eb91f321SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1499eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1500eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1501eb91f321SVaclav Hapla   if (isbinary) {
15028491ab44SLisandro Dalcin     ierr = MatLoad_Dense_Binary(newMat,viewer);CHKERRQ(ierr);
1503eb91f321SVaclav Hapla   } else if (ishdf5) {
1504eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
1505eb91f321SVaclav Hapla     ierr = MatLoad_Dense_HDF5(newMat,viewer);CHKERRQ(ierr);
1506eb91f321SVaclav Hapla #else
1507eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1508eb91f321SVaclav Hapla #endif
1509eb91f321SVaclav Hapla   } else {
1510eb91f321SVaclav 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);
1511eb91f321SVaclav Hapla   }
1512eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1513eb91f321SVaclav Hapla }
1514eb91f321SVaclav Hapla 
15156849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1516289bc588SBarry Smith {
1517932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1518dfbe8321SBarry Smith   PetscErrorCode    ierr;
151913f74950SBarry Smith   PetscInt          i,j;
15202dcb1b2aSMatthew Knepley   const char        *name;
1521ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1522f3ef73ceSBarry Smith   PetscViewerFormat format;
15235f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1524ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
15255f481a85SSatish Balay #endif
1526932b0c3eSLois Curfman McInnes 
15273a40ed3dSBarry Smith   PetscFunctionBegin;
1528ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1529b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1530456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
15313a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1532fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1533d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1534d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1535ca15aa20SStefano Zampini       v    = av + i;
153677431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1537d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1538aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1539329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
154057622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1541329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
154257622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
15436831982aSBarry Smith         }
154480cd9d93SLois Curfman McInnes #else
15456831982aSBarry Smith         if (*v) {
154657622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
15476831982aSBarry Smith         }
154880cd9d93SLois Curfman McInnes #endif
15491b807ce4Svictorle         v += a->lda;
155080cd9d93SLois Curfman McInnes       }
1551b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
155280cd9d93SLois Curfman McInnes     }
1553d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
15543a40ed3dSBarry Smith   } else {
1555d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1556aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
155747989497SBarry Smith     /* determine if matrix has all real values */
1558ca15aa20SStefano Zampini     v = av;
1559d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1560ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
156147989497SBarry Smith     }
156247989497SBarry Smith #endif
1563fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15643a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1565d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1566d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1567fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1568ffac6cdbSBarry Smith     }
1569ffac6cdbSBarry Smith 
1570d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1571ca15aa20SStefano Zampini       v = av + i;
1572d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1573aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
157447989497SBarry Smith         if (allreal) {
1575c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
157647989497SBarry Smith         } else {
1577c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
157847989497SBarry Smith         }
1579289bc588SBarry Smith #else
1580c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1581289bc588SBarry Smith #endif
15821b807ce4Svictorle         v += a->lda;
1583289bc588SBarry Smith       }
1584b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1585289bc588SBarry Smith     }
1586fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1587b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1588ffac6cdbSBarry Smith     }
1589d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1590da3a660dSBarry Smith   }
1591ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1592b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
15933a40ed3dSBarry Smith   PetscFunctionReturn(0);
1594289bc588SBarry Smith }
1595289bc588SBarry Smith 
15969804daf3SBarry Smith #include <petscdraw.h>
1597e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1598f1af5d2fSBarry Smith {
1599f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
16006849ba73SBarry Smith   PetscErrorCode    ierr;
1601383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1602383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1603ca15aa20SStefano Zampini   const PetscScalar *v;
1604b0a32e0cSBarry Smith   PetscViewer       viewer;
1605b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1606f3ef73ceSBarry Smith   PetscViewerFormat format;
1607f1af5d2fSBarry Smith 
1608f1af5d2fSBarry Smith   PetscFunctionBegin;
1609f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1610b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1611b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1612f1af5d2fSBarry Smith 
1613f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1614ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1615fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1616383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1617f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1618f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1619383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1620f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1621f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1622f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1623ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1624ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1625ca15aa20SStefano Zampini         else continue;
1626b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1627f1af5d2fSBarry Smith       }
1628f1af5d2fSBarry Smith     }
1629383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1630f1af5d2fSBarry Smith   } else {
1631f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1632f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1633b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1634b05fc000SLisandro Dalcin     PetscDraw popup;
1635b05fc000SLisandro Dalcin 
1636f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1637f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1638f1af5d2fSBarry Smith     }
1639383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1640b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
164145f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1642383922c3SLisandro Dalcin 
1643383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1644f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1645f1af5d2fSBarry Smith       x_l = j;
1646f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1647f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1648f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1649f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1650b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1651b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1652f1af5d2fSBarry Smith       }
1653f1af5d2fSBarry Smith     }
1654383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1655f1af5d2fSBarry Smith   }
1656ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1657f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1658f1af5d2fSBarry Smith }
1659f1af5d2fSBarry Smith 
1660e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1661f1af5d2fSBarry Smith {
1662b0a32e0cSBarry Smith   PetscDraw      draw;
1663ace3abfcSBarry Smith   PetscBool      isnull;
1664329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1665dfbe8321SBarry Smith   PetscErrorCode ierr;
1666f1af5d2fSBarry Smith 
1667f1af5d2fSBarry Smith   PetscFunctionBegin;
1668b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1669b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1670abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1671f1af5d2fSBarry Smith 
1672d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1673f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1674b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1675832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1676b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
16770298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1678832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1679f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1680f1af5d2fSBarry Smith }
1681f1af5d2fSBarry Smith 
1682dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1683932b0c3eSLois Curfman McInnes {
1684dfbe8321SBarry Smith   PetscErrorCode ierr;
1685ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1686932b0c3eSLois Curfman McInnes 
16873a40ed3dSBarry Smith   PetscFunctionBegin;
1688251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1689251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1690251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
16910f5bd95cSBarry Smith 
1692c45a1595SBarry Smith   if (iascii) {
1693c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
16940f5bd95cSBarry Smith   } else if (isbinary) {
1695637a0070SStefano Zampini     ierr = MatView_Dense_Binary(A,viewer);CHKERRQ(ierr);
1696f1af5d2fSBarry Smith   } else if (isdraw) {
1697f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1698932b0c3eSLois Curfman McInnes   }
16993a40ed3dSBarry Smith   PetscFunctionReturn(0);
1700932b0c3eSLois Curfman McInnes }
1701289bc588SBarry Smith 
1702637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array)
1703d3042a70SBarry Smith {
1704d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1705d3042a70SBarry Smith 
1706d3042a70SBarry Smith   PetscFunctionBegin;
17075ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
17085ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
17095ea7661aSPierre Jolivet   if (a->unplacedarray) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreArray() first");
1710d3042a70SBarry Smith   a->unplacedarray       = a->v;
1711d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1712d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1713637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1714ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1715c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1716ca15aa20SStefano Zampini #endif
1717d3042a70SBarry Smith   PetscFunctionReturn(0);
1718d3042a70SBarry Smith }
1719d3042a70SBarry Smith 
1720d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1721d3042a70SBarry Smith {
1722d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1723d3042a70SBarry Smith 
1724d3042a70SBarry Smith   PetscFunctionBegin;
17255ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
17265ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1727d3042a70SBarry Smith   a->v             = a->unplacedarray;
1728d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1729d3042a70SBarry Smith   a->unplacedarray = NULL;
1730ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1731c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1732ca15aa20SStefano Zampini #endif
1733d3042a70SBarry Smith   PetscFunctionReturn(0);
1734d3042a70SBarry Smith }
1735d3042a70SBarry Smith 
1736d5ea218eSStefano Zampini static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A,const PetscScalar *array)
1737d5ea218eSStefano Zampini {
1738d5ea218eSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1739d5ea218eSStefano Zampini   PetscErrorCode ierr;
1740d5ea218eSStefano Zampini 
1741d5ea218eSStefano Zampini   PetscFunctionBegin;
17425ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
17435ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1744d5ea218eSStefano Zampini   if (!a->user_alloc) { ierr = PetscFree(a->v);CHKERRQ(ierr); }
1745d5ea218eSStefano Zampini   a->v           = (PetscScalar*) array;
1746d5ea218eSStefano Zampini   a->user_alloc  = PETSC_FALSE;
1747d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1748d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1749d5ea218eSStefano Zampini #endif
1750d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1751d5ea218eSStefano Zampini }
1752d5ea218eSStefano Zampini 
1753ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1754289bc588SBarry Smith {
1755ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1756dfbe8321SBarry Smith   PetscErrorCode ierr;
175790f02eecSBarry Smith 
17583a40ed3dSBarry Smith   PetscFunctionBegin;
1759aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1760d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1761a5a9c739SBarry Smith #endif
17624396437dSToby Isaac   ierr = VecDestroy(&(l->qrrhs));CHKERRQ(ierr);
17634905a7bcSToby Isaac   ierr = PetscFree(l->tau);CHKERRQ(ierr);
176405b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1765a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1766abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
17676857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1768637a0070SStefano Zampini   if (!l->unplaced_user_alloc) {ierr = PetscFree(l->unplacedarray);CHKERRQ(ierr);}
17695ea7661aSPierre Jolivet   if (l->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
17705ea7661aSPierre Jolivet   if (l->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
17716947451fSStefano Zampini   ierr = VecDestroy(&l->cvec);CHKERRQ(ierr);
17725ea7661aSPierre Jolivet   ierr = MatDestroy(&l->cmat);CHKERRQ(ierr);
1773bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1774dbd8c25aSHong Zhang 
1775f4259b30SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)mat,NULL);CHKERRQ(ierr);
17764905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatQRFactor_C",NULL);CHKERRQ(ierr);
17774905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatQRFactorNumeric_C",NULL);CHKERRQ(ierr);
17784905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatQRFactorSymbolic_C",NULL);CHKERRQ(ierr);
177949a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1780ad16ce7aSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseSetLDA_C",NULL);CHKERRQ(ierr);
1781bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
178252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
1783d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1784d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
1785d5ea218eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseReplaceArray_C",NULL);CHKERRQ(ierr);
178652c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL);CHKERRQ(ierr);
178752c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL);CHKERRQ(ierr);
17886947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayWrite_C",NULL);CHKERRQ(ierr);
17896947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayWrite_C",NULL);CHKERRQ(ierr);
17908baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
17918baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17928baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
17938baccfbdSHong Zhang #endif
1794d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
1795d24d4204SJose E. Roman   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_scalapack_C",NULL);CHKERRQ(ierr);
1796d24d4204SJose E. Roman #endif
17972bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17982bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL);CHKERRQ(ierr);
17994222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL);CHKERRQ(ierr);
18004222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL);CHKERRQ(ierr);
18012bf066beSStefano Zampini #endif
1802bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
18034222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
18044222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL);CHKERRQ(ierr);
18054222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
18064222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
180752c5f739Sprj- 
180886aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
180986aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
18106947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVec_C",NULL);CHKERRQ(ierr);
18116947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVec_C",NULL);CHKERRQ(ierr);
18126947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecRead_C",NULL);CHKERRQ(ierr);
18136947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecRead_C",NULL);CHKERRQ(ierr);
18146947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecWrite_C",NULL);CHKERRQ(ierr);
18156947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecWrite_C",NULL);CHKERRQ(ierr);
18165ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetSubMatrix_C",NULL);CHKERRQ(ierr);
18175ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreSubMatrix_C",NULL);CHKERRQ(ierr);
18183a40ed3dSBarry Smith   PetscFunctionReturn(0);
1819289bc588SBarry Smith }
1820289bc588SBarry Smith 
1821e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1822289bc588SBarry Smith {
1823c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
18246849ba73SBarry Smith   PetscErrorCode ierr;
18256536e3caSStefano Zampini   PetscInt       k,j,m = A->rmap->n, M = mat->lda, n = A->cmap->n;
182687828ca2SBarry Smith   PetscScalar    *v,tmp;
182748b35521SBarry Smith 
18283a40ed3dSBarry Smith   PetscFunctionBegin;
18296536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
18306536e3caSStefano Zampini     if (m == n) { /* in place transpose */
1831ca15aa20SStefano Zampini       ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1832d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1833289bc588SBarry Smith         for (k=0; k<j; k++) {
18341b807ce4Svictorle           tmp        = v[j + k*M];
18351b807ce4Svictorle           v[j + k*M] = v[k + j*M];
18361b807ce4Svictorle           v[k + j*M] = tmp;
1837289bc588SBarry Smith         }
1838289bc588SBarry Smith       }
1839ca15aa20SStefano Zampini       ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
18406536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
18416536e3caSStefano Zampini       PetscScalar *v2;
18426536e3caSStefano Zampini       PetscLayout tmplayout;
18436536e3caSStefano Zampini 
18446536e3caSStefano Zampini       ierr = PetscMalloc1((size_t)m*n,&v2);CHKERRQ(ierr);
18456536e3caSStefano Zampini       ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
18466536e3caSStefano Zampini       for (j=0; j<n; j++) {
18476536e3caSStefano Zampini         for (k=0; k<m; k++) v2[j + (size_t)k*n] = v[k + (size_t)j*M];
18486536e3caSStefano Zampini       }
18496536e3caSStefano Zampini       ierr = PetscArraycpy(v,v2,(size_t)m*n);CHKERRQ(ierr);
18506536e3caSStefano Zampini       ierr = PetscFree(v2);CHKERRQ(ierr);
18516536e3caSStefano Zampini       ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
18526536e3caSStefano Zampini       /* cleanup size dependent quantities */
18536536e3caSStefano Zampini       ierr = VecDestroy(&mat->cvec);CHKERRQ(ierr);
18546536e3caSStefano Zampini       ierr = MatDestroy(&mat->cmat);CHKERRQ(ierr);
18556536e3caSStefano Zampini       ierr = PetscFree(mat->pivots);CHKERRQ(ierr);
18566536e3caSStefano Zampini       ierr = PetscFree(mat->fwork);CHKERRQ(ierr);
18576536e3caSStefano Zampini       ierr = MatDestroy(&mat->ptapwork);CHKERRQ(ierr);
18586536e3caSStefano Zampini       /* swap row/col layouts */
18596536e3caSStefano Zampini       mat->lda  = n;
18606536e3caSStefano Zampini       tmplayout = A->rmap;
18616536e3caSStefano Zampini       A->rmap   = A->cmap;
18626536e3caSStefano Zampini       A->cmap   = tmplayout;
18636536e3caSStefano Zampini     }
18643a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1865d3e5ee88SLois Curfman McInnes     Mat          tmat;
1866ec8511deSBarry Smith     Mat_SeqDense *tmatd;
186787828ca2SBarry Smith     PetscScalar  *v2;
1868af36a384SStefano Zampini     PetscInt     M2;
1869ea709b57SSatish Balay 
18706536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
1871ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1872d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
18737adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
18740298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1875ca15aa20SStefano Zampini     } else tmat = *matout;
1876ca15aa20SStefano Zampini 
1877ca15aa20SStefano Zampini     ierr  = MatDenseGetArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
1878ca15aa20SStefano Zampini     ierr  = MatDenseGetArray(tmat,&v2);CHKERRQ(ierr);
1879ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1880ca15aa20SStefano Zampini     M2    = tmatd->lda;
1881d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1882af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1883d3e5ee88SLois Curfman McInnes     }
1884ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(tmat,&v2);CHKERRQ(ierr);
1885ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
18866d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18876d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18886536e3caSStefano Zampini     *matout = tmat;
188948b35521SBarry Smith   }
18903a40ed3dSBarry Smith   PetscFunctionReturn(0);
1891289bc588SBarry Smith }
1892289bc588SBarry Smith 
1893e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1894289bc588SBarry Smith {
1895c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1896c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1897ca15aa20SStefano Zampini   PetscInt          i;
1898ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
1899ca15aa20SStefano Zampini   PetscErrorCode    ierr;
19009ea5d5aeSSatish Balay 
19013a40ed3dSBarry Smith   PetscFunctionBegin;
1902d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1903d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1904ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A1,&v1);CHKERRQ(ierr);
1905ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A2,&v2);CHKERRQ(ierr);
1906ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
1907ca15aa20SStefano Zampini     ierr = PetscArraycmp(v1,v2,A1->rmap->n,flg);CHKERRQ(ierr);
1908ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1909ca15aa20SStefano Zampini     v1 += mat1->lda;
1910ca15aa20SStefano Zampini     v2 += mat2->lda;
19111b807ce4Svictorle   }
1912ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A1,&v1);CHKERRQ(ierr);
1913ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A2,&v2);CHKERRQ(ierr);
191477c4ece6SBarry Smith   *flg = PETSC_TRUE;
19153a40ed3dSBarry Smith   PetscFunctionReturn(0);
1916289bc588SBarry Smith }
1917289bc588SBarry Smith 
1918e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1919289bc588SBarry Smith {
1920c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
192113f74950SBarry Smith   PetscInt          i,n,len;
1922ca15aa20SStefano Zampini   PetscScalar       *x;
1923ca15aa20SStefano Zampini   const PetscScalar *vv;
1924ca15aa20SStefano Zampini   PetscErrorCode    ierr;
192544cd7ae7SLois Curfman McInnes 
19263a40ed3dSBarry Smith   PetscFunctionBegin;
19277a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
19281ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1929d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1930ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1931e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
193244cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1933ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1934289bc588SBarry Smith   }
1935ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
19361ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
19373a40ed3dSBarry Smith   PetscFunctionReturn(0);
1938289bc588SBarry Smith }
1939289bc588SBarry Smith 
1940e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1941289bc588SBarry Smith {
1942c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1943f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1944ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1945dfbe8321SBarry Smith   PetscErrorCode    ierr;
1946d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
194755659b69SBarry Smith 
19483a40ed3dSBarry Smith   PetscFunctionBegin;
1949ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&vv);CHKERRQ(ierr);
195028988994SBarry Smith   if (ll) {
19517a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1952f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1953e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1954da3a660dSBarry Smith     for (i=0; i<m; i++) {
1955da3a660dSBarry Smith       x = l[i];
1956ca15aa20SStefano Zampini       v = vv + i;
1957b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1958da3a660dSBarry Smith     }
1959f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1960eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1961da3a660dSBarry Smith   }
196228988994SBarry Smith   if (rr) {
19637a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1964f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1965e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1966da3a660dSBarry Smith     for (i=0; i<n; i++) {
1967da3a660dSBarry Smith       x = r[i];
1968ca15aa20SStefano Zampini       v = vv + i*mat->lda;
19692205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1970da3a660dSBarry Smith     }
1971f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1972eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1973da3a660dSBarry Smith   }
1974ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&vv);CHKERRQ(ierr);
19753a40ed3dSBarry Smith   PetscFunctionReturn(0);
1976289bc588SBarry Smith }
1977289bc588SBarry Smith 
1978ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1979289bc588SBarry Smith {
1980c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1981ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1982329f5518SBarry Smith   PetscReal         sum  = 0.0;
1983d0f46423SBarry Smith   PetscInt          lda  =mat->lda,m=A->rmap->n,i,j;
1984efee365bSSatish Balay   PetscErrorCode    ierr;
198555659b69SBarry Smith 
19863a40ed3dSBarry Smith   PetscFunctionBegin;
1987ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
1988ca15aa20SStefano Zampini   v    = vv;
1989289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1990a5ce6ee0Svictorle     if (lda>m) {
1991d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1992ca15aa20SStefano Zampini         v = vv+j*lda;
1993a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1994a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1995a5ce6ee0Svictorle         }
1996a5ce6ee0Svictorle       }
1997a5ce6ee0Svictorle     } else {
1998570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1999570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
200073cf7048SBarry Smith       PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&cnt,v,&one));
2001570b7f6dSBarry Smith     }
2002570b7f6dSBarry Smith #else
2003d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
2004329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
2005289bc588SBarry Smith       }
2006a5ce6ee0Svictorle     }
20078f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
2008570b7f6dSBarry Smith #endif
2009dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
20103a40ed3dSBarry Smith   } else if (type == NORM_1) {
2011064f8208SBarry Smith     *nrm = 0.0;
2012d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2013ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
2014289bc588SBarry Smith       sum = 0.0;
2015d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
201633a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
2017289bc588SBarry Smith       }
2018064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
2019289bc588SBarry Smith     }
2020eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
20213a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2022064f8208SBarry Smith     *nrm = 0.0;
2023d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
2024ca15aa20SStefano Zampini       v   = vv + j;
2025289bc588SBarry Smith       sum = 0.0;
2026d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
20271b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
2028289bc588SBarry Smith       }
2029064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
2030289bc588SBarry Smith     }
2031eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
2032e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
2033ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
20343a40ed3dSBarry Smith   PetscFunctionReturn(0);
2035289bc588SBarry Smith }
2036289bc588SBarry Smith 
2037e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
2038289bc588SBarry Smith {
2039c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
204063ba0a88SBarry Smith   PetscErrorCode ierr;
204167e560aaSBarry Smith 
20423a40ed3dSBarry Smith   PetscFunctionBegin;
2043b5a2b587SKris Buschelman   switch (op) {
2044b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
20454e0d8c25SBarry Smith     aij->roworiented = flg;
2046b5a2b587SKris Buschelman     break;
2047512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
2048b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
20493971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
20508c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
205113fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
2052b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
2053b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
20540f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
20555021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
2056071fcb05SBarry Smith   case MAT_SORTED_FULL:
20575021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
20585021d80fSJed Brown     break;
20595021d80fSJed Brown   case MAT_SPD:
206077e54ba9SKris Buschelman   case MAT_SYMMETRIC:
206177e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
20629a4540c5SBarry Smith   case MAT_HERMITIAN:
20639a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
20645021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
206577e54ba9SKris Buschelman     break;
2066b5a2b587SKris Buschelman   default:
2067e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
20683a40ed3dSBarry Smith   }
20693a40ed3dSBarry Smith   PetscFunctionReturn(0);
2070289bc588SBarry Smith }
2071289bc588SBarry Smith 
2072e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
20736f0a148fSBarry Smith {
2074ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
20756849ba73SBarry Smith   PetscErrorCode ierr;
2076d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
2077ca15aa20SStefano Zampini   PetscScalar    *v;
20783a40ed3dSBarry Smith 
20793a40ed3dSBarry Smith   PetscFunctionBegin;
2080ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2081a5ce6ee0Svictorle   if (lda>m) {
2082d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2083ca15aa20SStefano Zampini       ierr = PetscArrayzero(v+j*lda,m);CHKERRQ(ierr);
2084a5ce6ee0Svictorle     }
2085a5ce6ee0Svictorle   } else {
2086ca15aa20SStefano Zampini     ierr = PetscArrayzero(v,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2087a5ce6ee0Svictorle   }
2088ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
20893a40ed3dSBarry Smith   PetscFunctionReturn(0);
20906f0a148fSBarry Smith }
20916f0a148fSBarry Smith 
2092e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
20936f0a148fSBarry Smith {
209497b48c8fSBarry Smith   PetscErrorCode    ierr;
2095ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
2096b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
2097ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
209897b48c8fSBarry Smith   const PetscScalar *xx;
209955659b69SBarry Smith 
21003a40ed3dSBarry Smith   PetscFunctionBegin;
210176bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2102b9679d65SBarry Smith     for (i=0; i<N; i++) {
2103b9679d65SBarry Smith       if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
2104b9679d65SBarry 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);
2105b9679d65SBarry Smith     }
210676bd3646SJed Brown   }
2107ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
2108b9679d65SBarry Smith 
210997b48c8fSBarry Smith   /* fix right hand side if needed */
211097b48c8fSBarry Smith   if (x && b) {
211197b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
211297b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
21132205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
211497b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
211597b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
211697b48c8fSBarry Smith   }
211797b48c8fSBarry Smith 
2118ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
21196f0a148fSBarry Smith   for (i=0; i<N; i++) {
2120ca15aa20SStefano Zampini     slot = v + rows[i];
2121b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
21226f0a148fSBarry Smith   }
2123f4df32b1SMatthew Knepley   if (diag != 0.0) {
2124b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
21256f0a148fSBarry Smith     for (i=0; i<N; i++) {
2126ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
2127f4df32b1SMatthew Knepley       *slot = diag;
21286f0a148fSBarry Smith     }
21296f0a148fSBarry Smith   }
2130ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
21313a40ed3dSBarry Smith   PetscFunctionReturn(0);
21326f0a148fSBarry Smith }
2133557bce09SLois Curfman McInnes 
213449a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
213549a6ff4bSBarry Smith {
213649a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
213749a6ff4bSBarry Smith 
213849a6ff4bSBarry Smith   PetscFunctionBegin;
213949a6ff4bSBarry Smith   *lda = mat->lda;
214049a6ff4bSBarry Smith   PetscFunctionReturn(0);
214149a6ff4bSBarry Smith }
214249a6ff4bSBarry Smith 
2143637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array)
214464e87e97SBarry Smith {
2145c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
21463a40ed3dSBarry Smith 
21473a40ed3dSBarry Smith   PetscFunctionBegin;
2148616b8fbbSStefano Zampini   if (mat->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
214964e87e97SBarry Smith   *array = mat->v;
21503a40ed3dSBarry Smith   PetscFunctionReturn(0);
215164e87e97SBarry Smith }
21520754003eSLois Curfman McInnes 
2153637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array)
2154ff14e315SSatish Balay {
21553a40ed3dSBarry Smith   PetscFunctionBegin;
2156637a0070SStefano Zampini   *array = NULL;
21573a40ed3dSBarry Smith   PetscFunctionReturn(0);
2158ff14e315SSatish Balay }
21590754003eSLois Curfman McInnes 
2160dec5eb66SMatthew G Knepley /*@C
216149a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
216249a6ff4bSBarry Smith 
2163ad16ce7aSStefano Zampini    Not collective
216449a6ff4bSBarry Smith 
216549a6ff4bSBarry Smith    Input Parameter:
216649a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
216749a6ff4bSBarry Smith 
216849a6ff4bSBarry Smith    Output Parameter:
216949a6ff4bSBarry Smith .   lda - the leading dimension
217049a6ff4bSBarry Smith 
217149a6ff4bSBarry Smith    Level: intermediate
217249a6ff4bSBarry Smith 
2173ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseSetLDA()
217449a6ff4bSBarry Smith @*/
217549a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
217649a6ff4bSBarry Smith {
217749a6ff4bSBarry Smith   PetscErrorCode ierr;
217849a6ff4bSBarry Smith 
217949a6ff4bSBarry Smith   PetscFunctionBegin;
2180d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2181d5ea218eSStefano Zampini   PetscValidPointer(lda,2);
218249a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
218349a6ff4bSBarry Smith   PetscFunctionReturn(0);
218449a6ff4bSBarry Smith }
218549a6ff4bSBarry Smith 
218649a6ff4bSBarry Smith /*@C
2187ad16ce7aSStefano Zampini    MatDenseSetLDA - Sets the leading dimension of the array used by the dense matrix
2188ad16ce7aSStefano Zampini 
2189ad16ce7aSStefano Zampini    Not collective
2190ad16ce7aSStefano Zampini 
2191ad16ce7aSStefano Zampini    Input Parameter:
2192ad16ce7aSStefano Zampini +  mat - a MATSEQDENSE or MATMPIDENSE matrix
2193ad16ce7aSStefano Zampini -  lda - the leading dimension
2194ad16ce7aSStefano Zampini 
2195ad16ce7aSStefano Zampini    Level: intermediate
2196ad16ce7aSStefano Zampini 
2197ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetLDA()
2198ad16ce7aSStefano Zampini @*/
2199ad16ce7aSStefano Zampini PetscErrorCode  MatDenseSetLDA(Mat A,PetscInt lda)
2200ad16ce7aSStefano Zampini {
2201ad16ce7aSStefano Zampini   PetscErrorCode ierr;
2202ad16ce7aSStefano Zampini 
2203ad16ce7aSStefano Zampini   PetscFunctionBegin;
2204ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2205ad16ce7aSStefano Zampini   ierr = PetscTryMethod(A,"MatDenseSetLDA_C",(Mat,PetscInt),(A,lda));CHKERRQ(ierr);
2206ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2207ad16ce7aSStefano Zampini }
2208ad16ce7aSStefano Zampini 
2209ad16ce7aSStefano Zampini /*@C
22106947451fSStefano Zampini    MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored
221173a71a0fSBarry Smith 
22128572280aSBarry Smith    Logically Collective on Mat
221373a71a0fSBarry Smith 
221473a71a0fSBarry Smith    Input Parameter:
22156947451fSStefano Zampini .  mat - a dense matrix
221673a71a0fSBarry Smith 
221773a71a0fSBarry Smith    Output Parameter:
221873a71a0fSBarry Smith .   array - pointer to the data
221973a71a0fSBarry Smith 
222073a71a0fSBarry Smith    Level: intermediate
222173a71a0fSBarry Smith 
22226947451fSStefano Zampini .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
222373a71a0fSBarry Smith @*/
22248c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
222573a71a0fSBarry Smith {
222673a71a0fSBarry Smith   PetscErrorCode ierr;
222773a71a0fSBarry Smith 
222873a71a0fSBarry Smith   PetscFunctionBegin;
2229d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2230d5ea218eSStefano Zampini   PetscValidPointer(array,2);
22318c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
223273a71a0fSBarry Smith   PetscFunctionReturn(0);
223373a71a0fSBarry Smith }
223473a71a0fSBarry Smith 
2235dec5eb66SMatthew G Knepley /*@C
2236579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
223773a71a0fSBarry Smith 
22388572280aSBarry Smith    Logically Collective on Mat
22398572280aSBarry Smith 
22408572280aSBarry Smith    Input Parameters:
22416947451fSStefano Zampini +  mat - a dense matrix
2242a2b725a8SWilliam Gropp -  array - pointer to the data
22438572280aSBarry Smith 
22448572280aSBarry Smith    Level: intermediate
22458572280aSBarry Smith 
22466947451fSStefano Zampini .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
22478572280aSBarry Smith @*/
22488572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
22498572280aSBarry Smith {
22508572280aSBarry Smith   PetscErrorCode ierr;
22518572280aSBarry Smith 
22528572280aSBarry Smith   PetscFunctionBegin;
2253d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2254d5ea218eSStefano Zampini   PetscValidPointer(array,2);
22558572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
22568572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
2257637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
2258637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2259637a0070SStefano Zampini #endif
22608572280aSBarry Smith   PetscFunctionReturn(0);
22618572280aSBarry Smith }
22628572280aSBarry Smith 
22638572280aSBarry Smith /*@C
22646947451fSStefano Zampini    MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored
22658572280aSBarry Smith 
22668572280aSBarry Smith    Not Collective
22678572280aSBarry Smith 
22688572280aSBarry Smith    Input Parameter:
22696947451fSStefano Zampini .  mat - a dense matrix
22708572280aSBarry Smith 
22718572280aSBarry Smith    Output Parameter:
22728572280aSBarry Smith .   array - pointer to the data
22738572280aSBarry Smith 
22748572280aSBarry Smith    Level: intermediate
22758572280aSBarry Smith 
22766947451fSStefano Zampini .seealso: MatDenseRestoreArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
22778572280aSBarry Smith @*/
22788572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
22798572280aSBarry Smith {
22808572280aSBarry Smith   PetscErrorCode ierr;
22818572280aSBarry Smith 
22828572280aSBarry Smith   PetscFunctionBegin;
2283d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2284d5ea218eSStefano Zampini   PetscValidPointer(array,2);
22858572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
22868572280aSBarry Smith   PetscFunctionReturn(0);
22878572280aSBarry Smith }
22888572280aSBarry Smith 
22898572280aSBarry Smith /*@C
22906947451fSStefano Zampini    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead()
22918572280aSBarry Smith 
229273a71a0fSBarry Smith    Not Collective
229373a71a0fSBarry Smith 
229473a71a0fSBarry Smith    Input Parameters:
22956947451fSStefano Zampini +  mat - a dense matrix
2296a2b725a8SWilliam Gropp -  array - pointer to the data
229773a71a0fSBarry Smith 
229873a71a0fSBarry Smith    Level: intermediate
229973a71a0fSBarry Smith 
23006947451fSStefano Zampini .seealso: MatDenseGetArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
230173a71a0fSBarry Smith @*/
23028572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
230373a71a0fSBarry Smith {
230473a71a0fSBarry Smith   PetscErrorCode ierr;
230573a71a0fSBarry Smith 
230673a71a0fSBarry Smith   PetscFunctionBegin;
2307d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2308d5ea218eSStefano Zampini   PetscValidPointer(array,2);
23098572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
231073a71a0fSBarry Smith   PetscFunctionReturn(0);
231173a71a0fSBarry Smith }
231273a71a0fSBarry Smith 
23136947451fSStefano Zampini /*@C
23146947451fSStefano Zampini    MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored
23156947451fSStefano Zampini 
23166947451fSStefano Zampini    Not Collective
23176947451fSStefano Zampini 
23186947451fSStefano Zampini    Input Parameter:
23196947451fSStefano Zampini .  mat - a dense matrix
23206947451fSStefano Zampini 
23216947451fSStefano Zampini    Output Parameter:
23226947451fSStefano Zampini .   array - pointer to the data
23236947451fSStefano Zampini 
23246947451fSStefano Zampini    Level: intermediate
23256947451fSStefano Zampini 
23266947451fSStefano Zampini .seealso: MatDenseRestoreArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
23276947451fSStefano Zampini @*/
23286947451fSStefano Zampini PetscErrorCode  MatDenseGetArrayWrite(Mat A,PetscScalar **array)
23296947451fSStefano Zampini {
23306947451fSStefano Zampini   PetscErrorCode ierr;
23316947451fSStefano Zampini 
23326947451fSStefano Zampini   PetscFunctionBegin;
2333d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2334d5ea218eSStefano Zampini   PetscValidPointer(array,2);
23356947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
23366947451fSStefano Zampini   PetscFunctionReturn(0);
23376947451fSStefano Zampini }
23386947451fSStefano Zampini 
23396947451fSStefano Zampini /*@C
23406947451fSStefano Zampini    MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite()
23416947451fSStefano Zampini 
23426947451fSStefano Zampini    Not Collective
23436947451fSStefano Zampini 
23446947451fSStefano Zampini    Input Parameters:
23456947451fSStefano Zampini +  mat - a dense matrix
23466947451fSStefano Zampini -  array - pointer to the data
23476947451fSStefano Zampini 
23486947451fSStefano Zampini    Level: intermediate
23496947451fSStefano Zampini 
23506947451fSStefano Zampini .seealso: MatDenseGetArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
23516947451fSStefano Zampini @*/
23526947451fSStefano Zampini PetscErrorCode  MatDenseRestoreArrayWrite(Mat A,PetscScalar **array)
23536947451fSStefano Zampini {
23546947451fSStefano Zampini   PetscErrorCode ierr;
23556947451fSStefano Zampini 
23566947451fSStefano Zampini   PetscFunctionBegin;
2357d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2358d5ea218eSStefano Zampini   PetscValidPointer(array,2);
23596947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
23606947451fSStefano Zampini   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
23616947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
23626947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
23636947451fSStefano Zampini #endif
23646947451fSStefano Zampini   PetscFunctionReturn(0);
23656947451fSStefano Zampini }
23666947451fSStefano Zampini 
2367023c16fcSToby Isaac static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,MatReuse scall,Mat *B)
23680754003eSLois Curfman McInnes {
2369c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
23706849ba73SBarry Smith   PetscErrorCode ierr;
2371ca15aa20SStefano Zampini   PetscInt       i,j,nrows,ncols,blda;
23725d0c19d7SBarry Smith   const PetscInt *irow,*icol;
237387828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
23740754003eSLois Curfman McInnes   Mat            newmat;
23750754003eSLois Curfman McInnes 
23763a40ed3dSBarry Smith   PetscFunctionBegin;
237778b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
237878b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
2379e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2380e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
23810754003eSLois Curfman McInnes 
2382182d2002SSatish Balay   /* Check submatrixcall */
2383182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
238413f74950SBarry Smith     PetscInt n_cols,n_rows;
2385182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
238621a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2387f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
2388c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
238921a2c019SBarry Smith     }
2390182d2002SSatish Balay     newmat = *B;
2391182d2002SSatish Balay   } else {
23920754003eSLois Curfman McInnes     /* Create and fill new matrix */
2393ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
2394f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
23957adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
23960298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
2397182d2002SSatish Balay   }
2398182d2002SSatish Balay 
2399182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
2400ca15aa20SStefano Zampini   ierr = MatDenseGetArray(newmat,&bv);CHKERRQ(ierr);
2401ca15aa20SStefano Zampini   ierr = MatDenseGetLDA(newmat,&blda);CHKERRQ(ierr);
2402182d2002SSatish Balay   for (i=0; i<ncols; i++) {
24036de62eeeSBarry Smith     av = v + mat->lda*icol[i];
2404ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
2405ca15aa20SStefano Zampini     bv += blda;
24060754003eSLois Curfman McInnes   }
2407ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(newmat,&bv);CHKERRQ(ierr);
2408182d2002SSatish Balay 
2409182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
24106d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24116d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24120754003eSLois Curfman McInnes 
24130754003eSLois Curfman McInnes   /* Free work space */
241478b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
241578b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2416182d2002SSatish Balay   *B   = newmat;
24173a40ed3dSBarry Smith   PetscFunctionReturn(0);
24180754003eSLois Curfman McInnes }
24190754003eSLois Curfman McInnes 
24207dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2421905e6a2fSBarry Smith {
24226849ba73SBarry Smith   PetscErrorCode ierr;
242313f74950SBarry Smith   PetscInt       i;
2424905e6a2fSBarry Smith 
24253a40ed3dSBarry Smith   PetscFunctionBegin;
2426905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
24273741e84bSPierre Jolivet     ierr = PetscCalloc1(n,B);CHKERRQ(ierr);
2428905e6a2fSBarry Smith   }
2429905e6a2fSBarry Smith 
2430905e6a2fSBarry Smith   for (i=0; i<n; i++) {
2431023c16fcSToby Isaac     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],scall,&(*B)[i]);CHKERRQ(ierr);
2432905e6a2fSBarry Smith   }
24333a40ed3dSBarry Smith   PetscFunctionReturn(0);
2434905e6a2fSBarry Smith }
2435905e6a2fSBarry Smith 
2436e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2437c0aa2d19SHong Zhang {
2438c0aa2d19SHong Zhang   PetscFunctionBegin;
2439c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2440c0aa2d19SHong Zhang }
2441c0aa2d19SHong Zhang 
2442e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2443c0aa2d19SHong Zhang {
2444c0aa2d19SHong Zhang   PetscFunctionBegin;
2445c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2446c0aa2d19SHong Zhang }
2447c0aa2d19SHong Zhang 
2448a76f77c3SStefano Zampini PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
24494b0e389bSBarry Smith {
24504b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
24516849ba73SBarry Smith   PetscErrorCode    ierr;
2452ca15aa20SStefano Zampini   const PetscScalar *va;
2453ca15aa20SStefano Zampini   PetscScalar       *vb;
2454d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
24553a40ed3dSBarry Smith 
24563a40ed3dSBarry Smith   PetscFunctionBegin;
245733f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
245833f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
2459cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
24603a40ed3dSBarry Smith     PetscFunctionReturn(0);
24613a40ed3dSBarry Smith   }
2462e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
2463ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&va);CHKERRQ(ierr);
2464ca15aa20SStefano Zampini   ierr = MatDenseGetArray(B,&vb);CHKERRQ(ierr);
2465a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
24660dbb7854Svictorle     for (j=0; j<n; j++) {
2467ca15aa20SStefano Zampini       ierr = PetscArraycpy(vb+j*lda2,va+j*lda1,m);CHKERRQ(ierr);
2468a5ce6ee0Svictorle     }
2469a5ce6ee0Svictorle   } else {
2470ca15aa20SStefano Zampini     ierr = PetscArraycpy(vb,va,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2471a5ce6ee0Svictorle   }
2472ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(B,&vb);CHKERRQ(ierr);
2473ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&va);CHKERRQ(ierr);
2474ca15aa20SStefano Zampini   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2475ca15aa20SStefano Zampini   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2476273d9f13SBarry Smith   PetscFunctionReturn(0);
2477273d9f13SBarry Smith }
2478273d9f13SBarry Smith 
2479e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
2480273d9f13SBarry Smith {
2481dfbe8321SBarry Smith   PetscErrorCode ierr;
2482273d9f13SBarry Smith 
2483273d9f13SBarry Smith   PetscFunctionBegin;
248418992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
248518992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
248618992e5dSStefano Zampini   if (!A->preallocated) {
2487f4259b30SLisandro Dalcin     ierr = MatSeqDenseSetPreallocation(A,NULL);CHKERRQ(ierr);
248818992e5dSStefano Zampini   }
24893a40ed3dSBarry Smith   PetscFunctionReturn(0);
24904b0e389bSBarry Smith }
24914b0e389bSBarry Smith 
2492ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2493ba337c44SJed Brown {
24944396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
2495ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
24964396437dSToby Isaac   PetscInt       min = PetscMin(A->rmap->n,A->cmap->n);
2497ca15aa20SStefano Zampini   PetscScalar    *aa;
2498ca15aa20SStefano Zampini   PetscErrorCode ierr;
2499ba337c44SJed Brown 
2500ba337c44SJed Brown   PetscFunctionBegin;
2501ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2502ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2503ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
25044396437dSToby Isaac   if (mat->tau) for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2505ba337c44SJed Brown   PetscFunctionReturn(0);
2506ba337c44SJed Brown }
2507ba337c44SJed Brown 
2508ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2509ba337c44SJed Brown {
2510ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2511ca15aa20SStefano Zampini   PetscScalar    *aa;
2512ca15aa20SStefano Zampini   PetscErrorCode ierr;
2513ba337c44SJed Brown 
2514ba337c44SJed Brown   PetscFunctionBegin;
2515ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2516ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2517ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2518ba337c44SJed Brown   PetscFunctionReturn(0);
2519ba337c44SJed Brown }
2520ba337c44SJed Brown 
2521ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2522ba337c44SJed Brown {
2523ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2524ca15aa20SStefano Zampini   PetscScalar    *aa;
2525ca15aa20SStefano Zampini   PetscErrorCode ierr;
2526ba337c44SJed Brown 
2527ba337c44SJed Brown   PetscFunctionBegin;
2528ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2529ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
2530ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2531ba337c44SJed Brown   PetscFunctionReturn(0);
2532ba337c44SJed Brown }
2533284134d9SBarry Smith 
2534a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
25354222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2536a9fe9ddaSSatish Balay {
2537ee16a9a1SHong Zhang   PetscErrorCode ierr;
2538d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
25397a3c3d58SStefano Zampini   PetscBool      cisdense;
2540a9fe9ddaSSatish Balay 
2541ee16a9a1SHong Zhang   PetscFunctionBegin;
25424222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
25437a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
25447a3c3d58SStefano Zampini   if (!cisdense) {
25457a3c3d58SStefano Zampini     PetscBool flg;
25467a3c3d58SStefano Zampini 
2547ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
25484222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
25497a3c3d58SStefano Zampini   }
255018992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2551ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2552ee16a9a1SHong Zhang }
2553a9fe9ddaSSatish Balay 
2554a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2555a9fe9ddaSSatish Balay {
25566718818eSStefano Zampini   Mat_SeqDense       *a=(Mat_SeqDense*)A->data,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
25570805154bSBarry Smith   PetscBLASInt       m,n,k;
2558ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2559ca15aa20SStefano Zampini   PetscScalar       *cv;
2560a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2561c2916339SPierre Jolivet   PetscErrorCode    ierr;
2562a9fe9ddaSSatish Balay 
2563a9fe9ddaSSatish Balay   PetscFunctionBegin;
25648208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
25658208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2566c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
256749d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
2568ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
2569ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
25706718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
2571ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
2572ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2573ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
2574ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
25756718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2576a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2577a9fe9ddaSSatish Balay }
2578a9fe9ddaSSatish Balay 
25794222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
258069f65d41SStefano Zampini {
258169f65d41SStefano Zampini   PetscErrorCode ierr;
258269f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
25837a3c3d58SStefano Zampini   PetscBool      cisdense;
258469f65d41SStefano Zampini 
258569f65d41SStefano Zampini   PetscFunctionBegin;
25864222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
25877a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
25887a3c3d58SStefano Zampini   if (!cisdense) {
25897a3c3d58SStefano Zampini     PetscBool flg;
25907a3c3d58SStefano Zampini 
2591ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
25924222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
25937a3c3d58SStefano Zampini   }
259418992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
259569f65d41SStefano Zampini   PetscFunctionReturn(0);
259669f65d41SStefano Zampini }
259769f65d41SStefano Zampini 
259869f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
259969f65d41SStefano Zampini {
260069f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
260169f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
260269f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
26036718818eSStefano Zampini   const PetscScalar *av,*bv;
26046718818eSStefano Zampini   PetscScalar       *cv;
260569f65d41SStefano Zampini   PetscBLASInt      m,n,k;
260669f65d41SStefano Zampini   PetscScalar       _DOne=1.0,_DZero=0.0;
260769f65d41SStefano Zampini   PetscErrorCode    ierr;
260869f65d41SStefano Zampini 
260969f65d41SStefano Zampini   PetscFunctionBegin;
261049d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
261149d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
261269f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
261349d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
26146718818eSStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
26156718818eSStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
26166718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
26176718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
26186718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
26196718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
26206718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2621ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
262269f65d41SStefano Zampini   PetscFunctionReturn(0);
262369f65d41SStefano Zampini }
262469f65d41SStefano Zampini 
26254222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2626a9fe9ddaSSatish Balay {
2627ee16a9a1SHong Zhang   PetscErrorCode ierr;
2628d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
26297a3c3d58SStefano Zampini   PetscBool      cisdense;
2630a9fe9ddaSSatish Balay 
2631ee16a9a1SHong Zhang   PetscFunctionBegin;
26324222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
26337a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
26347a3c3d58SStefano Zampini   if (!cisdense) {
26357a3c3d58SStefano Zampini     PetscBool flg;
26367a3c3d58SStefano Zampini 
2637ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
26384222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
26397a3c3d58SStefano Zampini   }
264018992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2641ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2642ee16a9a1SHong Zhang }
2643a9fe9ddaSSatish Balay 
264475648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2645a9fe9ddaSSatish Balay {
2646a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2647a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
2648a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
26496718818eSStefano Zampini   const PetscScalar *av,*bv;
26506718818eSStefano Zampini   PetscScalar       *cv;
26510805154bSBarry Smith   PetscBLASInt      m,n,k;
2652a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2653c5df96a5SBarry Smith   PetscErrorCode    ierr;
2654a9fe9ddaSSatish Balay 
2655a9fe9ddaSSatish Balay   PetscFunctionBegin;
26568208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
26578208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2658c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
265949d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
26606718818eSStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
26616718818eSStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
26626718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
26636718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
26646718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
26656718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
26666718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2667ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2668a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2669a9fe9ddaSSatish Balay }
2670985db425SBarry Smith 
26714222ddf1SHong Zhang /* ----------------------------------------------- */
26724222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
26734222ddf1SHong Zhang {
26744222ddf1SHong Zhang   PetscFunctionBegin;
26754222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
26764222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
26774222ddf1SHong Zhang   PetscFunctionReturn(0);
26784222ddf1SHong Zhang }
26794222ddf1SHong Zhang 
26804222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
26814222ddf1SHong Zhang {
26824222ddf1SHong Zhang   PetscFunctionBegin;
26834222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
26844222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
26854222ddf1SHong Zhang   PetscFunctionReturn(0);
26864222ddf1SHong Zhang }
26874222ddf1SHong Zhang 
26884222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
26894222ddf1SHong Zhang {
26904222ddf1SHong Zhang   PetscFunctionBegin;
26914222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
26924222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
26934222ddf1SHong Zhang   PetscFunctionReturn(0);
26944222ddf1SHong Zhang }
26954222ddf1SHong Zhang 
26964222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
26974222ddf1SHong Zhang {
26984222ddf1SHong Zhang   PetscErrorCode ierr;
26994222ddf1SHong Zhang   Mat_Product    *product = C->product;
27004222ddf1SHong Zhang 
27014222ddf1SHong Zhang   PetscFunctionBegin;
27024222ddf1SHong Zhang   switch (product->type) {
27034222ddf1SHong Zhang   case MATPRODUCT_AB:
27044222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AB(C);CHKERRQ(ierr);
27054222ddf1SHong Zhang     break;
27064222ddf1SHong Zhang   case MATPRODUCT_AtB:
27074222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AtB(C);CHKERRQ(ierr);
27084222ddf1SHong Zhang     break;
27094222ddf1SHong Zhang   case MATPRODUCT_ABt:
27104222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_ABt(C);CHKERRQ(ierr);
27114222ddf1SHong Zhang     break;
27126718818eSStefano Zampini   default:
27134222ddf1SHong Zhang     break;
27144222ddf1SHong Zhang   }
27154222ddf1SHong Zhang   PetscFunctionReturn(0);
27164222ddf1SHong Zhang }
27174222ddf1SHong Zhang /* ----------------------------------------------- */
27184222ddf1SHong Zhang 
2719e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2720985db425SBarry Smith {
2721985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2722985db425SBarry Smith   PetscErrorCode     ierr;
2723d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2724985db425SBarry Smith   PetscScalar        *x;
2725ca15aa20SStefano Zampini   const PetscScalar *aa;
2726985db425SBarry Smith 
2727985db425SBarry Smith   PetscFunctionBegin;
2728e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2729985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2730985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2731ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2732e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2733985db425SBarry Smith   for (i=0; i<m; i++) {
2734985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2735985db425SBarry Smith     for (j=1; j<n; j++) {
2736ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2737985db425SBarry Smith     }
2738985db425SBarry Smith   }
2739ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2740985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2741985db425SBarry Smith   PetscFunctionReturn(0);
2742985db425SBarry Smith }
2743985db425SBarry Smith 
2744e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2745985db425SBarry Smith {
2746985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2747985db425SBarry Smith   PetscErrorCode    ierr;
2748d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2749985db425SBarry Smith   PetscScalar       *x;
2750985db425SBarry Smith   PetscReal         atmp;
2751ca15aa20SStefano Zampini   const PetscScalar *aa;
2752985db425SBarry Smith 
2753985db425SBarry Smith   PetscFunctionBegin;
2754e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2755985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2756985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2757ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2758e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2759985db425SBarry Smith   for (i=0; i<m; i++) {
27609189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2761985db425SBarry Smith     for (j=1; j<n; j++) {
2762ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2763985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2764985db425SBarry Smith     }
2765985db425SBarry Smith   }
2766ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2767985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2768985db425SBarry Smith   PetscFunctionReturn(0);
2769985db425SBarry Smith }
2770985db425SBarry Smith 
2771e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2772985db425SBarry Smith {
2773985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2774985db425SBarry Smith   PetscErrorCode    ierr;
2775d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2776985db425SBarry Smith   PetscScalar       *x;
2777ca15aa20SStefano Zampini   const PetscScalar *aa;
2778985db425SBarry Smith 
2779985db425SBarry Smith   PetscFunctionBegin;
2780e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2781ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2782985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2783985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2784e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2785985db425SBarry Smith   for (i=0; i<m; i++) {
2786985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2787985db425SBarry Smith     for (j=1; j<n; j++) {
2788ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2789985db425SBarry Smith     }
2790985db425SBarry Smith   }
2791985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2792ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2793985db425SBarry Smith   PetscFunctionReturn(0);
2794985db425SBarry Smith }
2795985db425SBarry Smith 
2796637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
27978d0534beSBarry Smith {
27988d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
27998d0534beSBarry Smith   PetscErrorCode    ierr;
28008d0534beSBarry Smith   PetscScalar       *x;
2801ca15aa20SStefano Zampini   const PetscScalar *aa;
28028d0534beSBarry Smith 
28038d0534beSBarry Smith   PetscFunctionBegin;
2804e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2805ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
28068d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2807ca15aa20SStefano Zampini   ierr = PetscArraycpy(x,aa+col*a->lda,A->rmap->n);CHKERRQ(ierr);
28088d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2809ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
28108d0534beSBarry Smith   PetscFunctionReturn(0);
28118d0534beSBarry Smith }
28128d0534beSBarry Smith 
281352c5f739Sprj- PETSC_INTERN PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
28140716a85fSBarry Smith {
28150716a85fSBarry Smith   PetscErrorCode    ierr;
28160716a85fSBarry Smith   PetscInt          i,j,m,n;
28171683a169SBarry Smith   const PetscScalar *a;
28180716a85fSBarry Smith 
28190716a85fSBarry Smith   PetscFunctionBegin;
28200716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2821580bdb30SBarry Smith   ierr = PetscArrayzero(norms,n);CHKERRQ(ierr);
28221683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&a);CHKERRQ(ierr);
28230716a85fSBarry Smith   if (type == NORM_2) {
28240716a85fSBarry Smith     for (i=0; i<n; i++) {
28250716a85fSBarry Smith       for (j=0; j<m; j++) {
28260716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
28270716a85fSBarry Smith       }
28280716a85fSBarry Smith       a += m;
28290716a85fSBarry Smith     }
28300716a85fSBarry Smith   } else if (type == NORM_1) {
28310716a85fSBarry Smith     for (i=0; i<n; i++) {
28320716a85fSBarry Smith       for (j=0; j<m; j++) {
28330716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
28340716a85fSBarry Smith       }
28350716a85fSBarry Smith       a += m;
28360716a85fSBarry Smith     }
28370716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
28380716a85fSBarry Smith     for (i=0; i<n; i++) {
28390716a85fSBarry Smith       for (j=0; j<m; j++) {
28400716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
28410716a85fSBarry Smith       }
28420716a85fSBarry Smith       a += m;
28430716a85fSBarry Smith     }
2844ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
28451683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&a);CHKERRQ(ierr);
28460716a85fSBarry Smith   if (type == NORM_2) {
28478f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
28480716a85fSBarry Smith   }
28490716a85fSBarry Smith   PetscFunctionReturn(0);
28500716a85fSBarry Smith }
28510716a85fSBarry Smith 
285273a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
285373a71a0fSBarry Smith {
285473a71a0fSBarry Smith   PetscErrorCode ierr;
285573a71a0fSBarry Smith   PetscScalar    *a;
2856637a0070SStefano Zampini   PetscInt       lda,m,n,i,j;
285773a71a0fSBarry Smith 
285873a71a0fSBarry Smith   PetscFunctionBegin;
285973a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
2860637a0070SStefano Zampini   ierr = MatDenseGetLDA(x,&lda);CHKERRQ(ierr);
28618c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
2862637a0070SStefano Zampini   for (j=0; j<n; j++) {
2863637a0070SStefano Zampini     for (i=0; i<m; i++) {
2864637a0070SStefano Zampini       ierr = PetscRandomGetValue(rctx,a+j*lda+i);CHKERRQ(ierr);
2865637a0070SStefano Zampini     }
286673a71a0fSBarry Smith   }
28678c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
286873a71a0fSBarry Smith   PetscFunctionReturn(0);
286973a71a0fSBarry Smith }
287073a71a0fSBarry Smith 
28713b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
28723b49f96aSBarry Smith {
28733b49f96aSBarry Smith   PetscFunctionBegin;
28743b49f96aSBarry Smith   *missing = PETSC_FALSE;
28753b49f96aSBarry Smith   PetscFunctionReturn(0);
28763b49f96aSBarry Smith }
287773a71a0fSBarry Smith 
2878ca15aa20SStefano Zampini /* vals is not const */
2879af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
288086aefd0dSHong Zhang {
2881ca15aa20SStefano Zampini   PetscErrorCode ierr;
288286aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2883ca15aa20SStefano Zampini   PetscScalar    *v;
288486aefd0dSHong Zhang 
288586aefd0dSHong Zhang   PetscFunctionBegin;
288686aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2887ca15aa20SStefano Zampini   ierr  = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2888ca15aa20SStefano Zampini   *vals = v+col*a->lda;
2889ca15aa20SStefano Zampini   ierr  = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
289086aefd0dSHong Zhang   PetscFunctionReturn(0);
289186aefd0dSHong Zhang }
289286aefd0dSHong Zhang 
2893af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
289486aefd0dSHong Zhang {
289586aefd0dSHong Zhang   PetscFunctionBegin;
2896f4259b30SLisandro Dalcin   *vals = NULL; /* user cannot accidently use the array later */
289786aefd0dSHong Zhang   PetscFunctionReturn(0);
289886aefd0dSHong Zhang }
2899abc3b08eSStefano Zampini 
2900289bc588SBarry Smith /* -------------------------------------------------------------------*/
2901a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2902905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2903905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2904905e6a2fSBarry Smith                                         MatMult_SeqDense,
290597304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
29067c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
29077c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2908f4259b30SLisandro Dalcin                                         NULL,
2909f4259b30SLisandro Dalcin                                         NULL,
2910f4259b30SLisandro Dalcin                                         NULL,
2911f4259b30SLisandro Dalcin                                 /* 10*/ NULL,
2912905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2913905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
291441f059aeSBarry Smith                                         MatSOR_SeqDense,
2915ec8511deSBarry Smith                                         MatTranspose_SeqDense,
291697304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2917905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2918905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2919905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2920905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2921c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2922c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2923905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2924905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2925d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2926f4259b30SLisandro Dalcin                                         NULL,
2927f4259b30SLisandro Dalcin                                         NULL,
2928f4259b30SLisandro Dalcin                                         NULL,
2929f4259b30SLisandro Dalcin                                         NULL,
29304994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2931f4259b30SLisandro Dalcin                                         NULL,
2932f4259b30SLisandro Dalcin                                         NULL,
2933f4259b30SLisandro Dalcin                                         NULL,
2934f4259b30SLisandro Dalcin                                         NULL,
2935d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2936f4259b30SLisandro Dalcin                                         NULL,
2937f4259b30SLisandro Dalcin                                         NULL,
2938f4259b30SLisandro Dalcin                                         NULL,
2939f4259b30SLisandro Dalcin                                         NULL,
2940d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
29417dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2942f4259b30SLisandro Dalcin                                         NULL,
29434b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2944a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2945d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2946a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
29477d68702bSBarry Smith                                         MatShift_Basic,
2948f4259b30SLisandro Dalcin                                         NULL,
29493f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
295073a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2951f4259b30SLisandro Dalcin                                         NULL,
2952f4259b30SLisandro Dalcin                                         NULL,
2953f4259b30SLisandro Dalcin                                         NULL,
2954f4259b30SLisandro Dalcin                                         NULL,
2955f4259b30SLisandro Dalcin                                 /* 54*/ NULL,
2956f4259b30SLisandro Dalcin                                         NULL,
2957f4259b30SLisandro Dalcin                                         NULL,
2958f4259b30SLisandro Dalcin                                         NULL,
2959f4259b30SLisandro Dalcin                                         NULL,
2960023c16fcSToby Isaac                                 /* 59*/ MatCreateSubMatrix_SeqDense,
2961e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2962e03a110bSBarry Smith                                         MatView_SeqDense,
2963f4259b30SLisandro Dalcin                                         NULL,
2964f4259b30SLisandro Dalcin                                         NULL,
2965f4259b30SLisandro Dalcin                                 /* 64*/ NULL,
2966f4259b30SLisandro Dalcin                                         NULL,
2967f4259b30SLisandro Dalcin                                         NULL,
2968f4259b30SLisandro Dalcin                                         NULL,
2969f4259b30SLisandro Dalcin                                         NULL,
2970d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
2971f4259b30SLisandro Dalcin                                         NULL,
2972f4259b30SLisandro Dalcin                                         NULL,
2973f4259b30SLisandro Dalcin                                         NULL,
2974f4259b30SLisandro Dalcin                                         NULL,
2975f4259b30SLisandro Dalcin                                 /* 74*/ NULL,
2976f4259b30SLisandro Dalcin                                         NULL,
2977f4259b30SLisandro Dalcin                                         NULL,
2978f4259b30SLisandro Dalcin                                         NULL,
2979f4259b30SLisandro Dalcin                                         NULL,
2980f4259b30SLisandro Dalcin                                 /* 79*/ NULL,
2981f4259b30SLisandro Dalcin                                         NULL,
2982f4259b30SLisandro Dalcin                                         NULL,
2983f4259b30SLisandro Dalcin                                         NULL,
29845bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2985637a0070SStefano Zampini                                         MatIsSymmetric_SeqDense,
29861cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2987f4259b30SLisandro Dalcin                                         NULL,
2988f4259b30SLisandro Dalcin                                         NULL,
2989f4259b30SLisandro Dalcin                                         NULL,
2990f4259b30SLisandro Dalcin                                 /* 89*/ NULL,
2991f4259b30SLisandro Dalcin                                         NULL,
2992a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2993f4259b30SLisandro Dalcin                                         NULL,
2994f4259b30SLisandro Dalcin                                         NULL,
2995f4259b30SLisandro Dalcin                                 /* 94*/ NULL,
2996f4259b30SLisandro Dalcin                                         NULL,
2997f4259b30SLisandro Dalcin                                         NULL,
299869f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2999f4259b30SLisandro Dalcin                                         NULL,
30004222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
3001f4259b30SLisandro Dalcin                                         NULL,
3002f4259b30SLisandro Dalcin                                         NULL,
3003ba337c44SJed Brown                                         MatConjugate_SeqDense,
3004f4259b30SLisandro Dalcin                                         NULL,
3005f4259b30SLisandro Dalcin                                 /*104*/ NULL,
3006ba337c44SJed Brown                                         MatRealPart_SeqDense,
3007ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
3008f4259b30SLisandro Dalcin                                         NULL,
3009f4259b30SLisandro Dalcin                                         NULL,
3010f4259b30SLisandro Dalcin                                 /*109*/ NULL,
3011f4259b30SLisandro Dalcin                                         NULL,
30128d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
3013aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
30143b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
3015f4259b30SLisandro Dalcin                                 /*114*/ NULL,
3016f4259b30SLisandro Dalcin                                         NULL,
3017f4259b30SLisandro Dalcin                                         NULL,
3018f4259b30SLisandro Dalcin                                         NULL,
3019f4259b30SLisandro Dalcin                                         NULL,
3020f4259b30SLisandro Dalcin                                 /*119*/ NULL,
3021f4259b30SLisandro Dalcin                                         NULL,
3022f4259b30SLisandro Dalcin                                         NULL,
3023f4259b30SLisandro Dalcin                                         NULL,
3024f4259b30SLisandro Dalcin                                         NULL,
3025f4259b30SLisandro Dalcin                                 /*124*/ NULL,
30265df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
3027f4259b30SLisandro Dalcin                                         NULL,
3028f4259b30SLisandro Dalcin                                         NULL,
3029f4259b30SLisandro Dalcin                                         NULL,
3030f4259b30SLisandro Dalcin                                 /*129*/ NULL,
3031f4259b30SLisandro Dalcin                                         NULL,
3032f4259b30SLisandro Dalcin                                         NULL,
303375648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
3034f4259b30SLisandro Dalcin                                         NULL,
3035f4259b30SLisandro Dalcin                                 /*134*/ NULL,
3036f4259b30SLisandro Dalcin                                         NULL,
3037f4259b30SLisandro Dalcin                                         NULL,
3038f4259b30SLisandro Dalcin                                         NULL,
3039f4259b30SLisandro Dalcin                                         NULL,
3040f4259b30SLisandro Dalcin                                 /*139*/ NULL,
3041f4259b30SLisandro Dalcin                                         NULL,
3042f4259b30SLisandro Dalcin                                         NULL,
3043f4259b30SLisandro Dalcin                                         NULL,
3044f4259b30SLisandro Dalcin                                         NULL,
30454222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
3046f4259b30SLisandro Dalcin                                 /*145*/ NULL,
3047f4259b30SLisandro Dalcin                                         NULL,
3048f4259b30SLisandro Dalcin                                         NULL
3049985db425SBarry Smith };
305090ace30eSBarry Smith 
30514b828684SBarry Smith /*@C
3052fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
3053d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
3054d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
3055289bc588SBarry Smith 
3056d083f849SBarry Smith    Collective
3057db81eaa0SLois Curfman McInnes 
305820563c6bSBarry Smith    Input Parameters:
3059db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
30600c775827SLois Curfman McInnes .  m - number of rows
306118f449edSLois Curfman McInnes .  n - number of columns
30620298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
3063dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
306420563c6bSBarry Smith 
306520563c6bSBarry Smith    Output Parameter:
306644cd7ae7SLois Curfman McInnes .  A - the matrix
306720563c6bSBarry Smith 
3068b259b22eSLois Curfman McInnes    Notes:
306918f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
307018f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
30710298fd71SBarry Smith    set data=NULL.
307218f449edSLois Curfman McInnes 
3073027ccd11SLois Curfman McInnes    Level: intermediate
3074027ccd11SLois Curfman McInnes 
307569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
307620563c6bSBarry Smith @*/
30777087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
3078289bc588SBarry Smith {
3079dfbe8321SBarry Smith   PetscErrorCode ierr;
30803b2fbd54SBarry Smith 
30813a40ed3dSBarry Smith   PetscFunctionBegin;
3082f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3083f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3084273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
3085273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
3086273d9f13SBarry Smith   PetscFunctionReturn(0);
3087273d9f13SBarry Smith }
3088273d9f13SBarry Smith 
3089273d9f13SBarry Smith /*@C
3090273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
3091273d9f13SBarry Smith 
3092d083f849SBarry Smith    Collective
3093273d9f13SBarry Smith 
3094273d9f13SBarry Smith    Input Parameters:
30951c4f3114SJed Brown +  B - the matrix
30960298fd71SBarry Smith -  data - the array (or NULL)
3097273d9f13SBarry Smith 
3098273d9f13SBarry Smith    Notes:
3099273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
3100273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
3101284134d9SBarry Smith    need not call this routine.
3102273d9f13SBarry Smith 
3103273d9f13SBarry Smith    Level: intermediate
3104273d9f13SBarry Smith 
3105ad16ce7aSStefano Zampini .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatDenseSetLDA()
3106867c911aSBarry Smith 
3107273d9f13SBarry Smith @*/
31087087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
3109273d9f13SBarry Smith {
31104ac538c5SBarry Smith   PetscErrorCode ierr;
3111a23d5eceSKris Buschelman 
3112a23d5eceSKris Buschelman   PetscFunctionBegin;
3113d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
31144ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
3115a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3116a23d5eceSKris Buschelman }
3117a23d5eceSKris Buschelman 
31187087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
3119a23d5eceSKris Buschelman {
3120ad16ce7aSStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
3121dfbe8321SBarry Smith   PetscErrorCode ierr;
3122273d9f13SBarry Smith 
3123273d9f13SBarry Smith   PetscFunctionBegin;
3124616b8fbbSStefano Zampini   if (b->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
3125273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3126a868139aSShri Abhyankar 
312734ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
312834ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
312934ef9618SShri Abhyankar 
3130ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
313186d161a7SShri Abhyankar 
3132ad16ce7aSStefano Zampini   ierr = PetscIntMultError(b->lda,B->cmap->n,NULL);CHKERRQ(ierr);
31339e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
31349e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
3135ad16ce7aSStefano Zampini     ierr = PetscCalloc1((size_t)b->lda*B->cmap->n,&b->v);CHKERRQ(ierr);
3136ad16ce7aSStefano Zampini     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*B->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
31372205254eSKarl Rupp 
31389e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
3139273d9f13SBarry Smith   } else { /* user-allocated storage */
31409e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
3141273d9f13SBarry Smith     b->v          = data;
3142273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
3143273d9f13SBarry Smith   }
31440450473dSBarry Smith   B->assembled = PETSC_TRUE;
3145273d9f13SBarry Smith   PetscFunctionReturn(0);
3146273d9f13SBarry Smith }
3147273d9f13SBarry Smith 
314865b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3149cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
31508baccfbdSHong Zhang {
3151d77f618aSHong Zhang   Mat               mat_elemental;
3152d77f618aSHong Zhang   PetscErrorCode    ierr;
31531683a169SBarry Smith   const PetscScalar *array;
31541683a169SBarry Smith   PetscScalar       *v_colwise;
3155d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
3156d77f618aSHong Zhang 
31578baccfbdSHong Zhang   PetscFunctionBegin;
3158d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
31591683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&array);CHKERRQ(ierr);
3160d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3161d77f618aSHong Zhang   k = 0;
3162d77f618aSHong Zhang   for (j=0; j<N; j++) {
3163d77f618aSHong Zhang     cols[j] = j;
3164d77f618aSHong Zhang     for (i=0; i<M; i++) {
3165d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
3166d77f618aSHong Zhang     }
3167d77f618aSHong Zhang   }
3168d77f618aSHong Zhang   for (i=0; i<M; i++) {
3169d77f618aSHong Zhang     rows[i] = i;
3170d77f618aSHong Zhang   }
31711683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&array);CHKERRQ(ierr);
3172d77f618aSHong Zhang 
3173d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
3174d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
3175d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
3176d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
3177d77f618aSHong Zhang 
3178d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
3179d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
3180d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3181d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3182d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
3183d77f618aSHong Zhang 
3184511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
318528be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
3186d77f618aSHong Zhang   } else {
3187d77f618aSHong Zhang     *newmat = mat_elemental;
3188d77f618aSHong Zhang   }
31898baccfbdSHong Zhang   PetscFunctionReturn(0);
31908baccfbdSHong Zhang }
319165b80a83SHong Zhang #endif
31928baccfbdSHong Zhang 
319317359960SJose E. Roman PetscErrorCode  MatDenseSetLDA_SeqDense(Mat B,PetscInt lda)
31941b807ce4Svictorle {
31951b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
31967422da62SJose E. Roman   PetscBool    data;
319721a2c019SBarry Smith 
31981b807ce4Svictorle   PetscFunctionBegin;
31997422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
32007422da62SJose 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");
3201e32f2f54SBarry 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);
32021b807ce4Svictorle   b->lda = lda;
32031b807ce4Svictorle   PetscFunctionReturn(0);
32041b807ce4Svictorle }
32051b807ce4Svictorle 
3206d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
3207d528f656SJakub Kruzik {
3208d528f656SJakub Kruzik   PetscErrorCode ierr;
3209d528f656SJakub Kruzik   PetscMPIInt    size;
3210d528f656SJakub Kruzik 
3211d528f656SJakub Kruzik   PetscFunctionBegin;
3212ffc4695bSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr);
3213d528f656SJakub Kruzik   if (size == 1) {
3214d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
3215d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
3216d528f656SJakub Kruzik     } else {
3217d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
3218d528f656SJakub Kruzik     }
3219d528f656SJakub Kruzik   } else {
3220d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
3221d528f656SJakub Kruzik   }
3222d528f656SJakub Kruzik   PetscFunctionReturn(0);
3223d528f656SJakub Kruzik }
3224d528f656SJakub Kruzik 
32256947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
32266947451fSStefano Zampini {
32276947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32286947451fSStefano Zampini   PetscErrorCode ierr;
32296947451fSStefano Zampini 
32306947451fSStefano Zampini   PetscFunctionBegin;
32315ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
32325ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32336947451fSStefano Zampini   if (!a->cvec) {
32346947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
3235616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
32366947451fSStefano Zampini   }
32376947451fSStefano Zampini   a->vecinuse = col + 1;
32386947451fSStefano Zampini   ierr = MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
32396947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
32406947451fSStefano Zampini   *v   = a->cvec;
32416947451fSStefano Zampini   PetscFunctionReturn(0);
32426947451fSStefano Zampini }
32436947451fSStefano Zampini 
32446947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
32456947451fSStefano Zampini {
32466947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32476947451fSStefano Zampini   PetscErrorCode ierr;
32486947451fSStefano Zampini 
32496947451fSStefano Zampini   PetscFunctionBegin;
32505ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
32516947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
32526947451fSStefano Zampini   a->vecinuse = 0;
32536947451fSStefano Zampini   ierr = MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
32546947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
32556947451fSStefano Zampini   *v   = NULL;
32566947451fSStefano Zampini   PetscFunctionReturn(0);
32576947451fSStefano Zampini }
32586947451fSStefano Zampini 
32596947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
32606947451fSStefano Zampini {
32616947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32626947451fSStefano Zampini   PetscErrorCode ierr;
32636947451fSStefano Zampini 
32646947451fSStefano Zampini   PetscFunctionBegin;
32655ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
32665ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32676947451fSStefano Zampini   if (!a->cvec) {
32686947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
3269616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
32706947451fSStefano Zampini   }
32716947451fSStefano Zampini   a->vecinuse = col + 1;
32726947451fSStefano Zampini   ierr = MatDenseGetArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
32736947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
32746947451fSStefano Zampini   ierr = VecLockReadPush(a->cvec);CHKERRQ(ierr);
32756947451fSStefano Zampini   *v   = a->cvec;
32766947451fSStefano Zampini   PetscFunctionReturn(0);
32776947451fSStefano Zampini }
32786947451fSStefano Zampini 
32796947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
32806947451fSStefano Zampini {
32816947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32826947451fSStefano Zampini   PetscErrorCode ierr;
32836947451fSStefano Zampini 
32846947451fSStefano Zampini   PetscFunctionBegin;
32855ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
32866947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
32876947451fSStefano Zampini   a->vecinuse = 0;
32886947451fSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
32896947451fSStefano Zampini   ierr = VecLockReadPop(a->cvec);CHKERRQ(ierr);
32906947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
32916947451fSStefano Zampini   *v   = NULL;
32926947451fSStefano Zampini   PetscFunctionReturn(0);
32936947451fSStefano Zampini }
32946947451fSStefano Zampini 
32956947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
32966947451fSStefano Zampini {
32976947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32986947451fSStefano Zampini   PetscErrorCode ierr;
32996947451fSStefano Zampini 
33006947451fSStefano Zampini   PetscFunctionBegin;
33015ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
33025ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
33036947451fSStefano Zampini   if (!a->cvec) {
33046947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
3305616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
33066947451fSStefano Zampini   }
33076947451fSStefano Zampini   a->vecinuse = col + 1;
33086947451fSStefano Zampini   ierr = MatDenseGetArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
33096947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
33106947451fSStefano Zampini   *v   = a->cvec;
33116947451fSStefano Zampini   PetscFunctionReturn(0);
33126947451fSStefano Zampini }
33136947451fSStefano Zampini 
33146947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
33156947451fSStefano Zampini {
33166947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
33176947451fSStefano Zampini   PetscErrorCode ierr;
33186947451fSStefano Zampini 
33196947451fSStefano Zampini   PetscFunctionBegin;
33205ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
33216947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
33226947451fSStefano Zampini   a->vecinuse = 0;
33236947451fSStefano Zampini   ierr = MatDenseRestoreArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
33246947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
33256947451fSStefano Zampini   *v   = NULL;
33266947451fSStefano Zampini   PetscFunctionReturn(0);
33276947451fSStefano Zampini }
33286947451fSStefano Zampini 
33295ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
33305ea7661aSPierre Jolivet {
33315ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
33325ea7661aSPierre Jolivet   PetscErrorCode ierr;
33335ea7661aSPierre Jolivet 
33345ea7661aSPierre Jolivet   PetscFunctionBegin;
33355ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
33365ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
33375ea7661aSPierre Jolivet   if (a->cmat && cend-cbegin != a->cmat->cmap->N) {
33385ea7661aSPierre Jolivet     ierr = MatDestroy(&a->cmat);CHKERRQ(ierr);
33395ea7661aSPierre Jolivet   }
33405ea7661aSPierre Jolivet   if (!a->cmat) {
3341616b8fbbSStefano 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);
3342616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cmat);CHKERRQ(ierr);
33435ea7661aSPierre Jolivet   } else {
3344616b8fbbSStefano Zampini     ierr = MatDensePlaceArray(a->cmat,a->v + (size_t)cbegin * (size_t)a->lda);CHKERRQ(ierr);
33455ea7661aSPierre Jolivet   }
3346616b8fbbSStefano Zampini   ierr = MatDenseSetLDA(a->cmat,a->lda);CHKERRQ(ierr);
33475ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
33485ea7661aSPierre Jolivet   *v = a->cmat;
33495ea7661aSPierre Jolivet   PetscFunctionReturn(0);
33505ea7661aSPierre Jolivet }
33515ea7661aSPierre Jolivet 
33525ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A,Mat *v)
33535ea7661aSPierre Jolivet {
33545ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
33555ea7661aSPierre Jolivet   PetscErrorCode ierr;
33565ea7661aSPierre Jolivet 
33575ea7661aSPierre Jolivet   PetscFunctionBegin;
33585ea7661aSPierre Jolivet   if (!a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetSubMatrix() first");
33595ea7661aSPierre Jolivet   if (!a->cmat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column matrix");
3360616b8fbbSStefano Zampini   if (*v != a->cmat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not the matrix obtained from MatDenseGetSubMatrix()");
33615ea7661aSPierre Jolivet   a->matinuse = 0;
33625ea7661aSPierre Jolivet   ierr = MatDenseResetArray(a->cmat);CHKERRQ(ierr);
33635ea7661aSPierre Jolivet   *v   = NULL;
33645ea7661aSPierre Jolivet   PetscFunctionReturn(0);
33655ea7661aSPierre Jolivet }
33665ea7661aSPierre Jolivet 
33670bad9183SKris Buschelman /*MC
3368fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
33690bad9183SKris Buschelman 
33700bad9183SKris Buschelman    Options Database Keys:
33710bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
33720bad9183SKris Buschelman 
33730bad9183SKris Buschelman   Level: beginner
33740bad9183SKris Buschelman 
337589665df3SBarry Smith .seealso: MatCreateSeqDense()
337689665df3SBarry Smith 
33770bad9183SKris Buschelman M*/
3378ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
3379273d9f13SBarry Smith {
3380273d9f13SBarry Smith   Mat_SeqDense   *b;
3381dfbe8321SBarry Smith   PetscErrorCode ierr;
33827c334f02SBarry Smith   PetscMPIInt    size;
3383273d9f13SBarry Smith 
3384273d9f13SBarry Smith   PetscFunctionBegin;
3385ffc4695bSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRMPI(ierr);
3386e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
338755659b69SBarry Smith 
3388b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
3389549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
339044cd7ae7SLois Curfman McInnes   B->data = (void*)b;
339118f449edSLois Curfman McInnes 
3392273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
33934e220ebcSLois Curfman McInnes 
33944905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)B,"MatQRFactor_C",MatQRFactor_SeqDense);CHKERRQ(ierr);
33954905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)B,"MatQRFactorNumeric_C",MatQRFactorNumeric_SeqDense);CHKERRQ(ierr);
33964905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)B,"MatQRFactorSymbolic_C",MatQRFactorSymbolic_SeqDense);CHKERRQ(ierr);
339749a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
3398ad16ce7aSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseSetLDA_C",MatDenseSetLDA_SeqDense);CHKERRQ(ierr);
3399bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
34008572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
3401d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
3402d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
3403d5ea218eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseReplaceArray_C",MatDenseReplaceArray_SeqDense);CHKERRQ(ierr);
34048572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
3405715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
34066947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayWrite_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
34076947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayWrite_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
3408bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
34098baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
34108baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
34118baccfbdSHong Zhang #endif
3412d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
3413d24d4204SJose E. Roman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_scalapack_C",MatConvert_Dense_ScaLAPACK);CHKERRQ(ierr);
3414d24d4204SJose E. Roman #endif
34152bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
34162bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA);CHKERRQ(ierr);
34174222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
34184222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
3419637a0070SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
34202bf066beSStefano Zampini #endif
3421bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
34224222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
34234222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
34244222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
34254222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
342696e6d5c4SRichard Tran Mills 
3427af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
3428af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
34296947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVec_C",MatDenseGetColumnVec_SeqDense);CHKERRQ(ierr);
34306947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVec_C",MatDenseRestoreColumnVec_SeqDense);CHKERRQ(ierr);
34316947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecRead_C",MatDenseGetColumnVecRead_SeqDense);CHKERRQ(ierr);
34326947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecRead_C",MatDenseRestoreColumnVecRead_SeqDense);CHKERRQ(ierr);
34336947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecWrite_C",MatDenseGetColumnVecWrite_SeqDense);CHKERRQ(ierr);
34346947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecWrite_C",MatDenseRestoreColumnVecWrite_SeqDense);CHKERRQ(ierr);
34355ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetSubMatrix_C",MatDenseGetSubMatrix_SeqDense);CHKERRQ(ierr);
34365ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreSubMatrix_C",MatDenseRestoreSubMatrix_SeqDense);CHKERRQ(ierr);
343717667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
34383a40ed3dSBarry Smith   PetscFunctionReturn(0);
3439289bc588SBarry Smith }
344086aefd0dSHong Zhang 
344186aefd0dSHong Zhang /*@C
3442af53bab2SHong 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.
344386aefd0dSHong Zhang 
344486aefd0dSHong Zhang    Not Collective
344586aefd0dSHong Zhang 
34465ea7661aSPierre Jolivet    Input Parameters:
344786aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
344886aefd0dSHong Zhang -  col - column index
344986aefd0dSHong Zhang 
345086aefd0dSHong Zhang    Output Parameter:
345186aefd0dSHong Zhang .  vals - pointer to the data
345286aefd0dSHong Zhang 
345386aefd0dSHong Zhang    Level: intermediate
345486aefd0dSHong Zhang 
345586aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
345686aefd0dSHong Zhang @*/
345786aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
345886aefd0dSHong Zhang {
345986aefd0dSHong Zhang   PetscErrorCode ierr;
346086aefd0dSHong Zhang 
346186aefd0dSHong Zhang   PetscFunctionBegin;
3462d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3463d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3464d5ea218eSStefano Zampini   PetscValidPointer(vals,3);
346586aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
346686aefd0dSHong Zhang   PetscFunctionReturn(0);
346786aefd0dSHong Zhang }
346886aefd0dSHong Zhang 
346986aefd0dSHong Zhang /*@C
347086aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
347186aefd0dSHong Zhang 
347286aefd0dSHong Zhang    Not Collective
347386aefd0dSHong Zhang 
347486aefd0dSHong Zhang    Input Parameter:
347586aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
347686aefd0dSHong Zhang 
347786aefd0dSHong Zhang    Output Parameter:
347886aefd0dSHong Zhang .  vals - pointer to the data
347986aefd0dSHong Zhang 
348086aefd0dSHong Zhang    Level: intermediate
348186aefd0dSHong Zhang 
348286aefd0dSHong Zhang .seealso: MatDenseGetColumn()
348386aefd0dSHong Zhang @*/
348486aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
348586aefd0dSHong Zhang {
348686aefd0dSHong Zhang   PetscErrorCode ierr;
348786aefd0dSHong Zhang 
348886aefd0dSHong Zhang   PetscFunctionBegin;
3489d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3490d5ea218eSStefano Zampini   PetscValidPointer(vals,2);
349186aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
349286aefd0dSHong Zhang   PetscFunctionReturn(0);
349386aefd0dSHong Zhang }
34946947451fSStefano Zampini 
34956947451fSStefano Zampini /*@C
34966947451fSStefano Zampini    MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec.
34976947451fSStefano Zampini 
34986947451fSStefano Zampini    Collective
34996947451fSStefano Zampini 
35005ea7661aSPierre Jolivet    Input Parameters:
35016947451fSStefano Zampini +  mat - the Mat object
35026947451fSStefano Zampini -  col - the column index
35036947451fSStefano Zampini 
35046947451fSStefano Zampini    Output Parameter:
35056947451fSStefano Zampini .  v - the vector
35066947451fSStefano Zampini 
35076947451fSStefano Zampini    Notes:
35086947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed.
35096947451fSStefano Zampini      Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access.
35106947451fSStefano Zampini 
35116947451fSStefano Zampini    Level: intermediate
35126947451fSStefano Zampini 
35136947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
35146947451fSStefano Zampini @*/
35156947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec(Mat A,PetscInt col,Vec *v)
35166947451fSStefano Zampini {
35176947451fSStefano Zampini   PetscErrorCode ierr;
35186947451fSStefano Zampini 
35196947451fSStefano Zampini   PetscFunctionBegin;
35206947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35216947451fSStefano Zampini   PetscValidType(A,1);
35226947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35236947451fSStefano Zampini   PetscValidPointer(v,3);
35246947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35256947451fSStefano 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);
35266947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
35276947451fSStefano Zampini   PetscFunctionReturn(0);
35286947451fSStefano Zampini }
35296947451fSStefano Zampini 
35306947451fSStefano Zampini /*@C
35316947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
35326947451fSStefano Zampini 
35336947451fSStefano Zampini    Collective
35346947451fSStefano Zampini 
35355ea7661aSPierre Jolivet    Input Parameters:
35366947451fSStefano Zampini +  mat - the Mat object
35376947451fSStefano Zampini .  col - the column index
35386947451fSStefano Zampini -  v - the Vec object
35396947451fSStefano Zampini 
35406947451fSStefano Zampini    Level: intermediate
35416947451fSStefano Zampini 
35426947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
35436947451fSStefano Zampini @*/
35446947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec *v)
35456947451fSStefano Zampini {
35466947451fSStefano Zampini   PetscErrorCode ierr;
35476947451fSStefano Zampini 
35486947451fSStefano Zampini   PetscFunctionBegin;
35496947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35506947451fSStefano Zampini   PetscValidType(A,1);
35516947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35526947451fSStefano Zampini   PetscValidPointer(v,3);
35536947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35546947451fSStefano 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);
35556947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
35566947451fSStefano Zampini   PetscFunctionReturn(0);
35576947451fSStefano Zampini }
35586947451fSStefano Zampini 
35596947451fSStefano Zampini /*@C
35606947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
35616947451fSStefano Zampini 
35626947451fSStefano Zampini    Collective
35636947451fSStefano Zampini 
35645ea7661aSPierre Jolivet    Input Parameters:
35656947451fSStefano Zampini +  mat - the Mat object
35666947451fSStefano Zampini -  col - the column index
35676947451fSStefano Zampini 
35686947451fSStefano Zampini    Output Parameter:
35696947451fSStefano Zampini .  v - the vector
35706947451fSStefano Zampini 
35716947451fSStefano Zampini    Notes:
35726947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
35736947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
35746947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
35756947451fSStefano Zampini 
35766947451fSStefano Zampini    Level: intermediate
35776947451fSStefano Zampini 
35786947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
35796947451fSStefano Zampini @*/
35806947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec *v)
35816947451fSStefano Zampini {
35826947451fSStefano Zampini   PetscErrorCode ierr;
35836947451fSStefano Zampini 
35846947451fSStefano Zampini   PetscFunctionBegin;
35856947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35866947451fSStefano Zampini   PetscValidType(A,1);
35876947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35886947451fSStefano Zampini   PetscValidPointer(v,3);
35896947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35906947451fSStefano 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);
35916947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
35926947451fSStefano Zampini   PetscFunctionReturn(0);
35936947451fSStefano Zampini }
35946947451fSStefano Zampini 
35956947451fSStefano Zampini /*@C
35966947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
35976947451fSStefano Zampini 
35986947451fSStefano Zampini    Collective
35996947451fSStefano Zampini 
36005ea7661aSPierre Jolivet    Input Parameters:
36016947451fSStefano Zampini +  mat - the Mat object
36026947451fSStefano Zampini .  col - the column index
36036947451fSStefano Zampini -  v - the Vec object
36046947451fSStefano Zampini 
36056947451fSStefano Zampini    Level: intermediate
36066947451fSStefano Zampini 
36076947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecWrite()
36086947451fSStefano Zampini @*/
36096947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec *v)
36106947451fSStefano Zampini {
36116947451fSStefano Zampini   PetscErrorCode ierr;
36126947451fSStefano Zampini 
36136947451fSStefano Zampini   PetscFunctionBegin;
36146947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36156947451fSStefano Zampini   PetscValidType(A,1);
36166947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
36176947451fSStefano Zampini   PetscValidPointer(v,3);
36186947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
36196947451fSStefano 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);
36206947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
36216947451fSStefano Zampini   PetscFunctionReturn(0);
36226947451fSStefano Zampini }
36236947451fSStefano Zampini 
36246947451fSStefano Zampini /*@C
36256947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
36266947451fSStefano Zampini 
36276947451fSStefano Zampini    Collective
36286947451fSStefano Zampini 
36295ea7661aSPierre Jolivet    Input Parameters:
36306947451fSStefano Zampini +  mat - the Mat object
36316947451fSStefano Zampini -  col - the column index
36326947451fSStefano Zampini 
36336947451fSStefano Zampini    Output Parameter:
36346947451fSStefano Zampini .  v - the vector
36356947451fSStefano Zampini 
36366947451fSStefano Zampini    Notes:
36376947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
36386947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
36396947451fSStefano Zampini 
36406947451fSStefano Zampini    Level: intermediate
36416947451fSStefano Zampini 
36426947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
36436947451fSStefano Zampini @*/
36446947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec *v)
36456947451fSStefano Zampini {
36466947451fSStefano Zampini   PetscErrorCode ierr;
36476947451fSStefano Zampini 
36486947451fSStefano Zampini   PetscFunctionBegin;
36496947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36506947451fSStefano Zampini   PetscValidType(A,1);
36516947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
36526947451fSStefano Zampini   PetscValidPointer(v,3);
36536947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
36546947451fSStefano 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);
36556947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
36566947451fSStefano Zampini   PetscFunctionReturn(0);
36576947451fSStefano Zampini }
36586947451fSStefano Zampini 
36596947451fSStefano Zampini /*@C
36606947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
36616947451fSStefano Zampini 
36626947451fSStefano Zampini    Collective
36636947451fSStefano Zampini 
36645ea7661aSPierre Jolivet    Input Parameters:
36656947451fSStefano Zampini +  mat - the Mat object
36666947451fSStefano Zampini .  col - the column index
36676947451fSStefano Zampini -  v - the Vec object
36686947451fSStefano Zampini 
36696947451fSStefano Zampini    Level: intermediate
36706947451fSStefano Zampini 
36716947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead()
36726947451fSStefano Zampini @*/
36736947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec *v)
36746947451fSStefano Zampini {
36756947451fSStefano Zampini   PetscErrorCode ierr;
36766947451fSStefano Zampini 
36776947451fSStefano Zampini   PetscFunctionBegin;
36786947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36796947451fSStefano Zampini   PetscValidType(A,1);
36806947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
36816947451fSStefano Zampini   PetscValidPointer(v,3);
36826947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
36836947451fSStefano 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);
36846947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
36856947451fSStefano Zampini   PetscFunctionReturn(0);
36866947451fSStefano Zampini }
36875ea7661aSPierre Jolivet 
36885ea7661aSPierre Jolivet /*@C
36895ea7661aSPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of columns of a dense matrix, represented as a Mat.
36905ea7661aSPierre Jolivet 
36915ea7661aSPierre Jolivet    Collective
36925ea7661aSPierre Jolivet 
36935ea7661aSPierre Jolivet    Input Parameters:
36945ea7661aSPierre Jolivet +  mat - the Mat object
36955ea7661aSPierre Jolivet .  cbegin - the first index in the block
36965ea7661aSPierre Jolivet -  cend - the last index in the block
36975ea7661aSPierre Jolivet 
36985ea7661aSPierre Jolivet    Output Parameter:
36995ea7661aSPierre Jolivet .  v - the matrix
37005ea7661aSPierre Jolivet 
37015ea7661aSPierre Jolivet    Notes:
37025ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
37035ea7661aSPierre Jolivet 
37045ea7661aSPierre Jolivet    Level: intermediate
37055ea7661aSPierre Jolivet 
37065ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseRestoreSubMatrix()
37075ea7661aSPierre Jolivet @*/
37085ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
37095ea7661aSPierre Jolivet {
37105ea7661aSPierre Jolivet   PetscErrorCode ierr;
37115ea7661aSPierre Jolivet 
37125ea7661aSPierre Jolivet   PetscFunctionBegin;
37135ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
37145ea7661aSPierre Jolivet   PetscValidType(A,1);
37155ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cbegin,2);
37165ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cend,3);
37175ea7661aSPierre Jolivet   PetscValidPointer(v,4);
37185ea7661aSPierre Jolivet   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
37195ea7661aSPierre 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);
3720616b8fbbSStefano 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);
37215ea7661aSPierre Jolivet   ierr = PetscUseMethod(A,"MatDenseGetSubMatrix_C",(Mat,PetscInt,PetscInt,Mat*),(A,cbegin,cend,v));CHKERRQ(ierr);
37225ea7661aSPierre Jolivet   PetscFunctionReturn(0);
37235ea7661aSPierre Jolivet }
37245ea7661aSPierre Jolivet 
37255ea7661aSPierre Jolivet /*@C
37265ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
37275ea7661aSPierre Jolivet 
37285ea7661aSPierre Jolivet    Collective
37295ea7661aSPierre Jolivet 
37305ea7661aSPierre Jolivet    Input Parameters:
37315ea7661aSPierre Jolivet +  mat - the Mat object
37325ea7661aSPierre Jolivet -  v - the Mat object
37335ea7661aSPierre Jolivet 
37345ea7661aSPierre Jolivet    Level: intermediate
37355ea7661aSPierre Jolivet 
37365ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseGetSubMatrix()
37375ea7661aSPierre Jolivet @*/
37385ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix(Mat A,Mat *v)
37395ea7661aSPierre Jolivet {
37405ea7661aSPierre Jolivet   PetscErrorCode ierr;
37415ea7661aSPierre Jolivet 
37425ea7661aSPierre Jolivet   PetscFunctionBegin;
37435ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
37445ea7661aSPierre Jolivet   PetscValidType(A,1);
37455ea7661aSPierre Jolivet   PetscValidPointer(v,2);
37465ea7661aSPierre Jolivet   ierr = PetscUseMethod(A,"MatDenseRestoreSubMatrix_C",(Mat,Mat*),(A,v));CHKERRQ(ierr);
37475ea7661aSPierre Jolivet   PetscFunctionReturn(0);
37485ea7661aSPierre Jolivet }
3749