xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 6280eeca51a2e58d7bf6329728671d3c7dfd5a49)
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 
441bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, 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 
458bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, 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 
491bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, 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);
505bf5a80bcSToby Isaac   PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", &trans, &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,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);
509bf5a80bcSToby Isaac   PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "N", "N", &mat->rank,&nrhs,mat->v,&mat->lda,x,&ldx,&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++) {
514bf5a80bcSToby Isaac       x[j*ldx + 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 
521bf5a80bcSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, 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);
530bf5a80bcSToby Isaac     PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "T", "N", &m,&nrhs,mat->v,&mat->lda,x,&ldx,&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);
535bf5a80bcSToby Isaac     PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", "N", &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,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 
669bf5a80bcSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
6704905a7bcSToby Isaac {
6714905a7bcSToby Isaac   PetscErrorCode    ierr;
6724905a7bcSToby Isaac   const PetscScalar *b;
6734396437dSToby Isaac   PetscScalar       *y;
674bf5a80bcSToby Isaac   PetscInt          n, _ldb, _ldx;
675bf5a80bcSToby Isaac   PetscBLASInt      nrhs=0,m=0,k=0,ldb=0,ldx=0,ldy=0;
6764905a7bcSToby Isaac 
6774905a7bcSToby Isaac   PetscFunctionBegin;
678*6280eecaSJose E. Roman   *_ldy=0; *_m=0; *_nrhs=0; *_k=0; *_y = NULL;
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);
683bf5a80bcSToby Isaac   ierr = MatDenseGetLDA(B,&_ldb);CHKERRQ(ierr);
684bf5a80bcSToby Isaac   ierr = PetscBLASIntCast(_ldb, &ldb);CHKERRQ(ierr);
685bf5a80bcSToby Isaac   ierr = MatDenseGetLDA(X,&_ldx);CHKERRQ(ierr);
686bf5a80bcSToby Isaac   ierr = PetscBLASIntCast(_ldx, &ldx);CHKERRQ(ierr);
687bf5a80bcSToby Isaac   if (ldx < m) {
6884396437dSToby Isaac     ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
6894396437dSToby Isaac     ierr = PetscMalloc1(nrhs * m, &y);CHKERRQ(ierr);
690bf5a80bcSToby Isaac     if (ldb == m) {
691bf5a80bcSToby Isaac       ierr = PetscArraycpy(y,b,ldb*nrhs);CHKERRQ(ierr);
6924905a7bcSToby Isaac     } else {
6934905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
694bf5a80bcSToby Isaac         ierr = PetscArraycpy(&y[j*m],&b[j*ldb],m);CHKERRQ(ierr);
6954905a7bcSToby Isaac       }
6964905a7bcSToby Isaac     }
697bf5a80bcSToby Isaac     ldy = m;
6984396437dSToby Isaac     ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
6994905a7bcSToby Isaac   } else {
700bf5a80bcSToby Isaac     if (ldb == ldx) {
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++) {
707bf5a80bcSToby Isaac         ierr = PetscArraycpy(&y[j*ldx],&b[j*ldb],m);CHKERRQ(ierr);
7084905a7bcSToby Isaac       }
7094396437dSToby Isaac       ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
7104905a7bcSToby Isaac     }
711bf5a80bcSToby Isaac     ldy = ldx;
7124905a7bcSToby Isaac   }
7134396437dSToby Isaac   *_y    = y;
714bf5a80bcSToby Isaac   *_ldy = ldy;
7154396437dSToby Isaac   *_k    = k;
7164396437dSToby Isaac   *_m    = m;
7174396437dSToby Isaac   *_nrhs = nrhs;
7184396437dSToby Isaac   PetscFunctionReturn(0);
7194396437dSToby Isaac }
7204396437dSToby Isaac 
721bf5a80bcSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
7224396437dSToby Isaac {
7234396437dSToby Isaac   PetscScalar       *y;
724bf5a80bcSToby Isaac   PetscInt          _ldx;
725bf5a80bcSToby Isaac   PetscBLASInt      k,ldy,nrhs,ldx=0;
7264396437dSToby Isaac   PetscErrorCode    ierr;
7274396437dSToby Isaac 
7284396437dSToby Isaac   PetscFunctionBegin;
7294396437dSToby Isaac   y    = *_y;
7304396437dSToby Isaac   *_y  = NULL;
7314396437dSToby Isaac   k    = *_k;
732bf5a80bcSToby Isaac   ldy = *_ldy;
7334396437dSToby Isaac   nrhs = *_nrhs;
734bf5a80bcSToby Isaac   ierr = MatDenseGetLDA(X,&_ldx);CHKERRQ(ierr);
735bf5a80bcSToby Isaac   ierr = PetscBLASIntCast(_ldx, &ldx);CHKERRQ(ierr);
736bf5a80bcSToby Isaac   if (ldx != ldy) {
7374905a7bcSToby Isaac     PetscScalar *xv;
7384905a7bcSToby Isaac     ierr = MatDenseGetArray(X,&xv);CHKERRQ(ierr);
7394905a7bcSToby Isaac     for (PetscInt j = 0; j < nrhs; j++) {
740bf5a80bcSToby Isaac       ierr = PetscArraycpy(&xv[j*ldx],&y[j*ldy],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;
753bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7544396437dSToby Isaac   PetscErrorCode ierr;
7554396437dSToby Isaac 
7564396437dSToby Isaac   PetscFunctionBegin;
757bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
758bf5a80bcSToby Isaac   ierr = MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE);CHKERRQ(ierr);
759bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &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;
766bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7674396437dSToby Isaac   PetscErrorCode ierr;
7684396437dSToby Isaac 
7694396437dSToby Isaac   PetscFunctionBegin;
770bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
771bf5a80bcSToby Isaac   ierr = MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE);CHKERRQ(ierr);
772bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &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;
779bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7804396437dSToby Isaac   PetscErrorCode ierr;
7814396437dSToby Isaac 
7824396437dSToby Isaac   PetscFunctionBegin;
783bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
784bf5a80bcSToby Isaac   ierr = MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE);CHKERRQ(ierr);
785bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &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;
792bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7934396437dSToby Isaac   PetscErrorCode ierr;
7944396437dSToby Isaac 
7954396437dSToby Isaac   PetscFunctionBegin;
796bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
797bf5a80bcSToby Isaac   ierr = MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE);CHKERRQ(ierr);
798bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &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;
805bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
8064396437dSToby Isaac   PetscErrorCode ierr;
8074396437dSToby Isaac 
8084396437dSToby Isaac   PetscFunctionBegin;
809bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
810bf5a80bcSToby Isaac   ierr = MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k);CHKERRQ(ierr);
811bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &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;
818bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
8194396437dSToby Isaac   PetscErrorCode ierr;
8204396437dSToby Isaac 
8214396437dSToby Isaac   PetscFunctionBegin;
822bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
823bf5a80bcSToby Isaac   ierr = MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k);CHKERRQ(ierr);
824bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &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   PetscFunctionReturn(0);
8854396437dSToby Isaac }
8864396437dSToby Isaac 
887a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
888ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
889db4efbfdSBarry Smith {
890db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
891db4efbfdSBarry Smith   PetscErrorCode ierr;
892c5df96a5SBarry Smith   PetscBLASInt   info,n;
893db4efbfdSBarry Smith 
894db4efbfdSBarry Smith   PetscFunctionBegin;
895c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
896db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
897a49dc2a2SStefano Zampini   if (A->spd) {
89800121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
8998b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
90000121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
901a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
902a49dc2a2SStefano Zampini   } else if (A->hermitian) {
903a49dc2a2SStefano Zampini     if (!mat->pivots) {
904a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
905a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
906a49dc2a2SStefano Zampini     }
907a49dc2a2SStefano Zampini     if (!mat->fwork) {
908a49dc2a2SStefano Zampini       PetscScalar dummy;
909a49dc2a2SStefano Zampini 
910a49dc2a2SStefano Zampini       mat->lfwork = -1;
91100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
912a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
91300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
914a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
915a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
916a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
917a49dc2a2SStefano Zampini     }
91800121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
919a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
92000121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
921a49dc2a2SStefano Zampini #endif
922a49dc2a2SStefano Zampini   } else { /* symmetric case */
923a49dc2a2SStefano Zampini     if (!mat->pivots) {
924a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
925a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
926a49dc2a2SStefano Zampini     }
927a49dc2a2SStefano Zampini     if (!mat->fwork) {
928a49dc2a2SStefano Zampini       PetscScalar dummy;
929a49dc2a2SStefano Zampini 
930a49dc2a2SStefano Zampini       mat->lfwork = -1;
93100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
932a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
93300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
934a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
935a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
936a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
937a49dc2a2SStefano Zampini     }
93800121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
939a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
94000121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
941a49dc2a2SStefano Zampini   }
942e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
9438208b9aeSStefano Zampini 
9444396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
9454396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
9464396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
9474396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
948d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
9492205254eSKarl Rupp 
950f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
951f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
952f6224b95SHong Zhang 
953eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
954db4efbfdSBarry Smith   PetscFunctionReturn(0);
955db4efbfdSBarry Smith }
956db4efbfdSBarry Smith 
9574396437dSToby Isaac static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
958db4efbfdSBarry Smith {
959db4efbfdSBarry Smith   PetscErrorCode ierr;
960db4efbfdSBarry Smith   MatFactorInfo  info;
961db4efbfdSBarry Smith 
962db4efbfdSBarry Smith   PetscFunctionBegin;
963db4efbfdSBarry Smith   info.fill = 1.0;
9642205254eSKarl Rupp 
965c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
966f4259b30SLisandro Dalcin   ierr = (*fact->ops->choleskyfactor)(fact,NULL,&info);CHKERRQ(ierr);
967db4efbfdSBarry Smith   PetscFunctionReturn(0);
968db4efbfdSBarry Smith }
969db4efbfdSBarry Smith 
970ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
971db4efbfdSBarry Smith {
972db4efbfdSBarry Smith   PetscFunctionBegin;
973c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9741bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
975719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
976db4efbfdSBarry Smith   PetscFunctionReturn(0);
977db4efbfdSBarry Smith }
978db4efbfdSBarry Smith 
979bf5a80bcSToby Isaac PetscErrorCode MatQRFactor_SeqDense(Mat A,IS col,const MatFactorInfo *minfo)
9804905a7bcSToby Isaac {
9814905a7bcSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
9824905a7bcSToby Isaac   PetscErrorCode ierr;
9834905a7bcSToby Isaac   PetscBLASInt   n,m,info, min, max;
9844905a7bcSToby Isaac 
9854905a7bcSToby Isaac   PetscFunctionBegin;
9864905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
9874905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
9884396437dSToby Isaac   max = PetscMax(m, n);
9894396437dSToby Isaac   min = PetscMin(m, n);
9904905a7bcSToby Isaac   if (!mat->tau) {
9914396437dSToby Isaac     ierr = PetscMalloc1(min,&mat->tau);CHKERRQ(ierr);
9924396437dSToby Isaac     ierr = PetscLogObjectMemory((PetscObject)A,min*sizeof(PetscScalar));CHKERRQ(ierr);
9934396437dSToby Isaac   }
9944396437dSToby Isaac   if (!mat->pivots) {
995bf5a80bcSToby Isaac     ierr = PetscMalloc1(n,&mat->pivots);CHKERRQ(ierr);
996bf5a80bcSToby Isaac     ierr = PetscLogObjectMemory((PetscObject)A,n*sizeof(PetscScalar));CHKERRQ(ierr);
9974396437dSToby Isaac   }
9984396437dSToby Isaac   if (!mat->qrrhs) {
9994396437dSToby Isaac     ierr = MatCreateVecs(A, NULL, &(mat->qrrhs));CHKERRQ(ierr);
10004905a7bcSToby Isaac   }
10014905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
10024905a7bcSToby Isaac   if (!mat->fwork) {
10034905a7bcSToby Isaac     PetscScalar dummy;
10044905a7bcSToby Isaac 
10054905a7bcSToby Isaac     mat->lfwork = -1;
10064905a7bcSToby Isaac     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
10074905a7bcSToby Isaac     PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,&dummy,&mat->lfwork,&info));
10084905a7bcSToby Isaac     ierr = PetscFPTrapPop();CHKERRQ(ierr);
10094905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
10104905a7bcSToby Isaac     ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
10114905a7bcSToby Isaac     ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
10124905a7bcSToby Isaac   }
10134905a7bcSToby Isaac   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
10144905a7bcSToby Isaac   PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,mat->fwork,&mat->lfwork,&info));
10154905a7bcSToby Isaac   ierr = PetscFPTrapPop();CHKERRQ(ierr);
10164905a7bcSToby Isaac   if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to QR factorization");
10174905a7bcSToby 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
10184905a7bcSToby Isaac   mat->rank = min;
10194905a7bcSToby Isaac 
10204396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_QR;
10214396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_QR;
10224905a7bcSToby Isaac   A->factortype             = MAT_FACTOR_QR;
10234905a7bcSToby Isaac   if (m == n) {
10244396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
10254396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
10264905a7bcSToby Isaac   }
10274905a7bcSToby Isaac 
10284905a7bcSToby Isaac   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
10294905a7bcSToby Isaac   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
10304905a7bcSToby Isaac 
10314905a7bcSToby Isaac   ierr = PetscLogFlops(2.0*min*min*(max-min/3.0));CHKERRQ(ierr);
10324905a7bcSToby Isaac   PetscFunctionReturn(0);
10334905a7bcSToby Isaac }
10344905a7bcSToby Isaac 
10354905a7bcSToby Isaac static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
10364905a7bcSToby Isaac {
10374905a7bcSToby Isaac   PetscErrorCode ierr;
10384905a7bcSToby Isaac   MatFactorInfo  info;
10394905a7bcSToby Isaac 
10404905a7bcSToby Isaac   PetscFunctionBegin;
10414905a7bcSToby Isaac   info.fill = 1.0;
10424905a7bcSToby Isaac 
10434905a7bcSToby Isaac   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
1044bf5a80bcSToby Isaac   ierr = PetscUseMethod(fact,"MatQRFactor_C",(Mat,IS,const MatFactorInfo *),(fact,NULL,&info));CHKERRQ(ierr);
10454905a7bcSToby Isaac   PetscFunctionReturn(0);
10464905a7bcSToby Isaac }
10474905a7bcSToby Isaac 
1048bf5a80bcSToby Isaac PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
10494905a7bcSToby Isaac {
10504905a7bcSToby Isaac   PetscErrorCode ierr;
10514905a7bcSToby Isaac 
10524905a7bcSToby Isaac   PetscFunctionBegin;
10534905a7bcSToby Isaac   fact->assembled                  = PETSC_TRUE;
10544905a7bcSToby Isaac   fact->preallocated               = PETSC_TRUE;
10554905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)fact,"MatQRFactorNumeric_C",MatQRFactorNumeric_SeqDense);CHKERRQ(ierr);
10564905a7bcSToby Isaac   PetscFunctionReturn(0);
10574905a7bcSToby Isaac }
10584905a7bcSToby Isaac 
1059ca15aa20SStefano Zampini /* uses LAPACK */
1060cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
1061db4efbfdSBarry Smith {
1062db4efbfdSBarry Smith   PetscErrorCode ierr;
1063db4efbfdSBarry Smith 
1064db4efbfdSBarry Smith   PetscFunctionBegin;
1065ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
1066db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1067ca15aa20SStefano Zampini   ierr = MatSetType(*fact,MATDENSE);CHKERRQ(ierr);
106866e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
10692a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
1070db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
10712a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
1072bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) {
1073db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
1074bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_QR) {
1075bf5a80bcSToby Isaac     ierr = PetscObjectComposeFunction((PetscObject)(*fact),"MatQRFactorSymbolic_C",MatQRFactorSymbolic_SeqDense);CHKERRQ(ierr);
1076db4efbfdSBarry Smith   }
1077d5f3da31SBarry Smith   (*fact)->factortype = ftype;
107800c67f3bSHong Zhang 
107900c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
108000c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
10814ac6704cSBarry Smith   ierr = PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_LU]);CHKERRQ(ierr);
10824ac6704cSBarry Smith   ierr = PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ILU]);CHKERRQ(ierr);
10834ac6704cSBarry Smith   ierr = PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]);CHKERRQ(ierr);
10844ac6704cSBarry Smith   ierr = PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ICC]);CHKERRQ(ierr);
1085db4efbfdSBarry Smith   PetscFunctionReturn(0);
1086db4efbfdSBarry Smith }
1087db4efbfdSBarry Smith 
1088289bc588SBarry Smith /* ------------------------------------------------------------------*/
1089e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
1090289bc588SBarry Smith {
1091c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1092d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
1093d9ca1df4SBarry Smith   const PetscScalar *b;
1094dfbe8321SBarry Smith   PetscErrorCode    ierr;
1095d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
109623fff9afSBarry Smith   PetscBLASInt      o = 1,bm = 0;
1097289bc588SBarry Smith 
10983a40ed3dSBarry Smith   PetscFunctionBegin;
1099ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1100c70f7ee4SJunchao Zhang   if (A->offloadmask == PETSC_OFFLOAD_GPU) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
1101ca15aa20SStefano Zampini #endif
1102422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
1103c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
1104289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
11053bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
11062dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
1107289bc588SBarry Smith   }
11081ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1109d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1110b965ef7fSBarry Smith   its  = its*lits;
1111e32f2f54SBarry 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);
1112289bc588SBarry Smith   while (its--) {
1113fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1114289bc588SBarry Smith       for (i=0; i<m; i++) {
11153bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
111655a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1117289bc588SBarry Smith       }
1118289bc588SBarry Smith     }
1119fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1120289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
11213bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
112255a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1123289bc588SBarry Smith       }
1124289bc588SBarry Smith     }
1125289bc588SBarry Smith   }
1126d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
11271ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11283a40ed3dSBarry Smith   PetscFunctionReturn(0);
1129289bc588SBarry Smith }
1130289bc588SBarry Smith 
1131289bc588SBarry Smith /* -----------------------------------------------------------------*/
1132ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
1133289bc588SBarry Smith {
1134c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1135d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
1136d9ca1df4SBarry Smith   PetscScalar       *y;
1137dfbe8321SBarry Smith   PetscErrorCode    ierr;
11380805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
1139ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
11403a40ed3dSBarry Smith 
11413a40ed3dSBarry Smith   PetscFunctionBegin;
1142c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1143c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
1144d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11452bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
11465ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11475ac36cfcSBarry Smith     PetscBLASInt i;
11485ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
11495ac36cfcSBarry Smith   } else {
11508b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
11515ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
11525ac36cfcSBarry Smith   }
1153d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
11542bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
11553a40ed3dSBarry Smith   PetscFunctionReturn(0);
1156289bc588SBarry Smith }
1157800995b7SMatthew Knepley 
1158ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
1159289bc588SBarry Smith {
1160c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1161d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
1162dfbe8321SBarry Smith   PetscErrorCode    ierr;
11630805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
1164d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
11653a40ed3dSBarry Smith 
11663a40ed3dSBarry Smith   PetscFunctionBegin;
1167c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1168c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
1169d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11702bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
11715ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11725ac36cfcSBarry Smith     PetscBLASInt i;
11735ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
11745ac36cfcSBarry Smith   } else {
11758b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
11765ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
11775ac36cfcSBarry Smith   }
1178d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
11792bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
11803a40ed3dSBarry Smith   PetscFunctionReturn(0);
1181289bc588SBarry Smith }
11826ee01492SSatish Balay 
1183ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1184289bc588SBarry Smith {
1185c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1186d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1187d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
1188dfbe8321SBarry Smith   PetscErrorCode    ierr;
11890805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
11903a40ed3dSBarry Smith 
11913a40ed3dSBarry Smith   PetscFunctionBegin;
1192c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1193c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
119417b127eeSStefano Zampini   ierr = VecCopy(zz,yy);CHKERRQ(ierr);
1195d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
1196d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11971ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
11988b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
1199d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12001ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1201dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
12023a40ed3dSBarry Smith   PetscFunctionReturn(0);
1203289bc588SBarry Smith }
12046ee01492SSatish Balay 
1205ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1206289bc588SBarry Smith {
1207c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1208d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1209d9ca1df4SBarry Smith   PetscScalar       *y;
1210dfbe8321SBarry Smith   PetscErrorCode    ierr;
12110805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
121287828ca2SBarry Smith   PetscScalar       _DOne=1.0;
12133a40ed3dSBarry Smith 
12143a40ed3dSBarry Smith   PetscFunctionBegin;
1215c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1216c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
121717b127eeSStefano Zampini   ierr = VecCopy(zz,yy);CHKERRQ(ierr);
1218d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
1219d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12201ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
12218b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
1222d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12231ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1224dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
12253a40ed3dSBarry Smith   PetscFunctionReturn(0);
1226289bc588SBarry Smith }
1227289bc588SBarry Smith 
1228289bc588SBarry Smith /* -----------------------------------------------------------------*/
1229e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1230289bc588SBarry Smith {
1231c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
12326849ba73SBarry Smith   PetscErrorCode ierr;
123313f74950SBarry Smith   PetscInt       i;
123467e560aaSBarry Smith 
12353a40ed3dSBarry Smith   PetscFunctionBegin;
1236d0f46423SBarry Smith   *ncols = A->cmap->n;
1237289bc588SBarry Smith   if (cols) {
12383741e84bSPierre Jolivet     ierr = PetscMalloc1(A->cmap->n,cols);CHKERRQ(ierr);
1239d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
1240289bc588SBarry Smith   }
1241289bc588SBarry Smith   if (vals) {
1242ca15aa20SStefano Zampini     const PetscScalar *v;
1243ca15aa20SStefano Zampini 
1244ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
12453741e84bSPierre Jolivet     ierr = PetscMalloc1(A->cmap->n,vals);CHKERRQ(ierr);
1246ca15aa20SStefano Zampini     v   += row;
1247d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
1248ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1249289bc588SBarry Smith   }
12503a40ed3dSBarry Smith   PetscFunctionReturn(0);
1251289bc588SBarry Smith }
12526ee01492SSatish Balay 
1253e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1254289bc588SBarry Smith {
1255dfbe8321SBarry Smith   PetscErrorCode ierr;
12566e111a19SKarl Rupp 
1257606d414cSSatish Balay   PetscFunctionBegin;
1258cb4a9cd9SHong Zhang   if (ncols) *ncols = 0;
1259606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
1260606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
12613a40ed3dSBarry Smith   PetscFunctionReturn(0);
1262289bc588SBarry Smith }
1263289bc588SBarry Smith /* ----------------------------------------------------------------*/
1264e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
1265289bc588SBarry Smith {
1266c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
1267ca15aa20SStefano Zampini   PetscScalar      *av;
126813f74950SBarry Smith   PetscInt         i,j,idx=0;
1269ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1270c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1271ca15aa20SStefano Zampini #endif
1272ca15aa20SStefano Zampini   PetscErrorCode   ierr;
1273d6dfbf8fSBarry Smith 
12743a40ed3dSBarry Smith   PetscFunctionBegin;
1275ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&av);CHKERRQ(ierr);
1276289bc588SBarry Smith   if (!mat->roworiented) {
1277dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1278289bc588SBarry Smith       for (j=0; j<n; j++) {
1279cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
1280cf9c20a2SJed 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);
1281289bc588SBarry Smith         for (i=0; i<m; i++) {
1282cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
1283cf9c20a2SJed 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);
1284ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1285289bc588SBarry Smith         }
1286289bc588SBarry Smith       }
12873a40ed3dSBarry Smith     } else {
1288289bc588SBarry Smith       for (j=0; j<n; j++) {
1289cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
1290cf9c20a2SJed 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);
1291289bc588SBarry Smith         for (i=0; i<m; i++) {
1292cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
1293cf9c20a2SJed 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);
1294ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1295289bc588SBarry Smith         }
1296289bc588SBarry Smith       }
1297289bc588SBarry Smith     }
12983a40ed3dSBarry Smith   } else {
1299dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1300e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
1301cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
1302cf9c20a2SJed 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);
1303e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
1304cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
1305cf9c20a2SJed 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);
1306ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1307e8d4e0b9SBarry Smith         }
1308e8d4e0b9SBarry Smith       }
13093a40ed3dSBarry Smith     } else {
1310289bc588SBarry Smith       for (i=0; i<m; i++) {
1311cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
1312cf9c20a2SJed 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);
1313289bc588SBarry Smith         for (j=0; j<n; j++) {
1314cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
1315cf9c20a2SJed 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);
1316ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1317289bc588SBarry Smith         }
1318289bc588SBarry Smith       }
1319289bc588SBarry Smith     }
1320e8d4e0b9SBarry Smith   }
1321ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
1322ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1323c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
1324c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1325ca15aa20SStefano Zampini #endif
1326ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&av);CHKERRQ(ierr);
1327ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1328c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1329ca15aa20SStefano Zampini #endif
13303a40ed3dSBarry Smith   PetscFunctionReturn(0);
1331289bc588SBarry Smith }
1332e8d4e0b9SBarry Smith 
1333e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1334ae80bb75SLois Curfman McInnes {
1335ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1336ca15aa20SStefano Zampini   const PetscScalar *vv;
133713f74950SBarry Smith   PetscInt          i,j;
1338ca15aa20SStefano Zampini   PetscErrorCode    ierr;
1339ae80bb75SLois Curfman McInnes 
13403a40ed3dSBarry Smith   PetscFunctionBegin;
1341ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1342ae80bb75SLois Curfman McInnes   /* row-oriented output */
1343ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
134497e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1345e32f2f54SBarry 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);
1346ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
13476f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1348e32f2f54SBarry 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);
1349ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1350ae80bb75SLois Curfman McInnes     }
1351ae80bb75SLois Curfman McInnes   }
1352ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
13533a40ed3dSBarry Smith   PetscFunctionReturn(0);
1354ae80bb75SLois Curfman McInnes }
1355ae80bb75SLois Curfman McInnes 
1356289bc588SBarry Smith /* -----------------------------------------------------------------*/
1357289bc588SBarry Smith 
13588491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1359aabbc4fbSShri Abhyankar {
1360aabbc4fbSShri Abhyankar   PetscErrorCode    ierr;
13618491ab44SLisandro Dalcin   PetscBool         skipHeader;
13628491ab44SLisandro Dalcin   PetscViewerFormat format;
13638491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
13648491ab44SLisandro Dalcin   const PetscScalar *v;
13658491ab44SLisandro Dalcin   PetscScalar       *vwork;
1366aabbc4fbSShri Abhyankar 
1367aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13688491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
13698491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
13708491ab44SLisandro Dalcin   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
13718491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1372aabbc4fbSShri Abhyankar 
13738491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
13748491ab44SLisandro Dalcin 
13758491ab44SLisandro Dalcin   /* write matrix header */
13768491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
13778491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
13788491ab44SLisandro Dalcin   if (!skipHeader) {ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);}
13798491ab44SLisandro Dalcin 
13808491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
13818491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13828491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
13838491ab44SLisandro Dalcin     /* store row lengths for each row */
13848491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
13858491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
13868491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
13878491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13888491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
13898491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
13908491ab44SLisandro Dalcin         iwork[k] = j;
13918491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
13928491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
13938491ab44SLisandro Dalcin   }
13948491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13958491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
13968491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
13978491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
13988491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
13998491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
14008491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
14018491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
14028491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
14038491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
14048491ab44SLisandro Dalcin   PetscFunctionReturn(0);
14058491ab44SLisandro Dalcin }
14068491ab44SLisandro Dalcin 
14078491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
14088491ab44SLisandro Dalcin {
14098491ab44SLisandro Dalcin   PetscErrorCode ierr;
14108491ab44SLisandro Dalcin   PetscBool      skipHeader;
14118491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
14128491ab44SLisandro Dalcin   PetscInt       rows,cols;
14138491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
14148491ab44SLisandro Dalcin 
14158491ab44SLisandro Dalcin   PetscFunctionBegin;
14168491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
14178491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
14188491ab44SLisandro Dalcin 
14198491ab44SLisandro Dalcin   if (!skipHeader) {
14208491ab44SLisandro Dalcin     ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
14218491ab44SLisandro Dalcin     if (header[0] != MAT_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
14228491ab44SLisandro Dalcin     M = header[1]; N = header[2];
14238491ab44SLisandro Dalcin     if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M);
14248491ab44SLisandro Dalcin     if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N);
14258491ab44SLisandro Dalcin     nz = header[3];
14268491ab44SLisandro Dalcin     if (nz != MATRIX_BINARY_FORMAT_DENSE && nz < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %D in file",nz);
1427aabbc4fbSShri Abhyankar   } else {
14288491ab44SLisandro Dalcin     ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
14298491ab44SLisandro 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");
14308491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1431e6324fbbSBarry Smith   }
1432aabbc4fbSShri Abhyankar 
14338491ab44SLisandro Dalcin   /* setup global sizes if not set */
14348491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
14358491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
14368491ab44SLisandro Dalcin   ierr = MatSetUp(mat);CHKERRQ(ierr);
14378491ab44SLisandro Dalcin   /* check if global sizes are correct */
14388491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
14398491ab44SLisandro 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);
1440aabbc4fbSShri Abhyankar 
14418491ab44SLisandro Dalcin   ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
14428491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
14438491ab44SLisandro Dalcin   ierr = MatDenseGetArray(mat,&v);CHKERRQ(ierr);
14448491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
14458491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
14468491ab44SLisandro Dalcin     PetscInt nnz = m*N;
14478491ab44SLisandro Dalcin     /* read in matrix values */
14488491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&vwork);CHKERRQ(ierr);
14498491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
14508491ab44SLisandro Dalcin     /* store values in column major order */
14518491ab44SLisandro Dalcin     for (j=0; j<N; j++)
14528491ab44SLisandro Dalcin       for (i=0; i<m; i++)
14538491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
14548491ab44SLisandro Dalcin     ierr = PetscFree(vwork);CHKERRQ(ierr);
14558491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14568491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14578491ab44SLisandro Dalcin     /* read in row lengths */
14588491ab44SLisandro Dalcin     ierr = PetscMalloc1(m,&rlens);CHKERRQ(ierr);
14598491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
14608491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
14618491ab44SLisandro Dalcin     /* read in column indices and values */
14628491ab44SLisandro Dalcin     ierr = PetscMalloc2(nnz,&icols,nnz,&vwork);CHKERRQ(ierr);
14638491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
14648491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
14658491ab44SLisandro Dalcin     /* store values in column major order */
14668491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
14678491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
14688491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
14698491ab44SLisandro Dalcin     ierr = PetscFree(rlens);CHKERRQ(ierr);
14708491ab44SLisandro Dalcin     ierr = PetscFree2(icols,vwork);CHKERRQ(ierr);
1471aabbc4fbSShri Abhyankar   }
14728491ab44SLisandro Dalcin   ierr = MatDenseRestoreArray(mat,&v);CHKERRQ(ierr);
14738491ab44SLisandro Dalcin   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14748491ab44SLisandro Dalcin   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1475aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1476aabbc4fbSShri Abhyankar }
1477aabbc4fbSShri Abhyankar 
1478eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1479eb91f321SVaclav Hapla {
1480eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1481eb91f321SVaclav Hapla   PetscErrorCode ierr;
1482eb91f321SVaclav Hapla 
1483eb91f321SVaclav Hapla   PetscFunctionBegin;
1484eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1485eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1486eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
1487eb91f321SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1488eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1489eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1490eb91f321SVaclav Hapla   if (isbinary) {
14918491ab44SLisandro Dalcin     ierr = MatLoad_Dense_Binary(newMat,viewer);CHKERRQ(ierr);
1492eb91f321SVaclav Hapla   } else if (ishdf5) {
1493eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
1494eb91f321SVaclav Hapla     ierr = MatLoad_Dense_HDF5(newMat,viewer);CHKERRQ(ierr);
1495eb91f321SVaclav Hapla #else
1496eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1497eb91f321SVaclav Hapla #endif
1498eb91f321SVaclav Hapla   } else {
1499eb91f321SVaclav 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);
1500eb91f321SVaclav Hapla   }
1501eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1502eb91f321SVaclav Hapla }
1503eb91f321SVaclav Hapla 
15046849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1505289bc588SBarry Smith {
1506932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1507dfbe8321SBarry Smith   PetscErrorCode    ierr;
150813f74950SBarry Smith   PetscInt          i,j;
15092dcb1b2aSMatthew Knepley   const char        *name;
1510ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1511f3ef73ceSBarry Smith   PetscViewerFormat format;
15125f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1513ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
15145f481a85SSatish Balay #endif
1515932b0c3eSLois Curfman McInnes 
15163a40ed3dSBarry Smith   PetscFunctionBegin;
1517ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1518b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1519456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
15203a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1521fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1522d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1523d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1524ca15aa20SStefano Zampini       v    = av + i;
152577431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1526d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1527aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1528329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
152957622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1530329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
153157622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
15326831982aSBarry Smith         }
153380cd9d93SLois Curfman McInnes #else
15346831982aSBarry Smith         if (*v) {
153557622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
15366831982aSBarry Smith         }
153780cd9d93SLois Curfman McInnes #endif
15381b807ce4Svictorle         v += a->lda;
153980cd9d93SLois Curfman McInnes       }
1540b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
154180cd9d93SLois Curfman McInnes     }
1542d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
15433a40ed3dSBarry Smith   } else {
1544d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1545aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
154647989497SBarry Smith     /* determine if matrix has all real values */
1547ca15aa20SStefano Zampini     v = av;
1548d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1549ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
155047989497SBarry Smith     }
155147989497SBarry Smith #endif
1552fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15533a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1554d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1555d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1556fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1557ffac6cdbSBarry Smith     }
1558ffac6cdbSBarry Smith 
1559d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1560ca15aa20SStefano Zampini       v = av + i;
1561d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1562aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
156347989497SBarry Smith         if (allreal) {
1564c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
156547989497SBarry Smith         } else {
1566c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
156747989497SBarry Smith         }
1568289bc588SBarry Smith #else
1569c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1570289bc588SBarry Smith #endif
15711b807ce4Svictorle         v += a->lda;
1572289bc588SBarry Smith       }
1573b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1574289bc588SBarry Smith     }
1575fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1576b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1577ffac6cdbSBarry Smith     }
1578d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1579da3a660dSBarry Smith   }
1580ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1581b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
15823a40ed3dSBarry Smith   PetscFunctionReturn(0);
1583289bc588SBarry Smith }
1584289bc588SBarry Smith 
15859804daf3SBarry Smith #include <petscdraw.h>
1586e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1587f1af5d2fSBarry Smith {
1588f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
15896849ba73SBarry Smith   PetscErrorCode    ierr;
1590383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1591383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1592ca15aa20SStefano Zampini   const PetscScalar *v;
1593b0a32e0cSBarry Smith   PetscViewer       viewer;
1594b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1595f3ef73ceSBarry Smith   PetscViewerFormat format;
1596f1af5d2fSBarry Smith 
1597f1af5d2fSBarry Smith   PetscFunctionBegin;
1598f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1599b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1600b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1601f1af5d2fSBarry Smith 
1602f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1603ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1604fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1605383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1606f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1607f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1608383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1609f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1610f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1611f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1612ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1613ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1614ca15aa20SStefano Zampini         else continue;
1615b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1616f1af5d2fSBarry Smith       }
1617f1af5d2fSBarry Smith     }
1618383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1619f1af5d2fSBarry Smith   } else {
1620f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1621f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1622b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1623b05fc000SLisandro Dalcin     PetscDraw popup;
1624b05fc000SLisandro Dalcin 
1625f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1626f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1627f1af5d2fSBarry Smith     }
1628383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1629b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
163045f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1631383922c3SLisandro Dalcin 
1632383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1633f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1634f1af5d2fSBarry Smith       x_l = j;
1635f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1636f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1637f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1638f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1639b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1640b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1641f1af5d2fSBarry Smith       }
1642f1af5d2fSBarry Smith     }
1643383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1644f1af5d2fSBarry Smith   }
1645ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1646f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1647f1af5d2fSBarry Smith }
1648f1af5d2fSBarry Smith 
1649e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1650f1af5d2fSBarry Smith {
1651b0a32e0cSBarry Smith   PetscDraw      draw;
1652ace3abfcSBarry Smith   PetscBool      isnull;
1653329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1654dfbe8321SBarry Smith   PetscErrorCode ierr;
1655f1af5d2fSBarry Smith 
1656f1af5d2fSBarry Smith   PetscFunctionBegin;
1657b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1658b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1659abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1660f1af5d2fSBarry Smith 
1661d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1662f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1663b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1664832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1665b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
16660298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1667832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1668f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1669f1af5d2fSBarry Smith }
1670f1af5d2fSBarry Smith 
1671dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1672932b0c3eSLois Curfman McInnes {
1673dfbe8321SBarry Smith   PetscErrorCode ierr;
1674ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1675932b0c3eSLois Curfman McInnes 
16763a40ed3dSBarry Smith   PetscFunctionBegin;
1677251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1678251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1679251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
16800f5bd95cSBarry Smith 
1681c45a1595SBarry Smith   if (iascii) {
1682c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
16830f5bd95cSBarry Smith   } else if (isbinary) {
1684637a0070SStefano Zampini     ierr = MatView_Dense_Binary(A,viewer);CHKERRQ(ierr);
1685f1af5d2fSBarry Smith   } else if (isdraw) {
1686f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1687932b0c3eSLois Curfman McInnes   }
16883a40ed3dSBarry Smith   PetscFunctionReturn(0);
1689932b0c3eSLois Curfman McInnes }
1690289bc588SBarry Smith 
1691637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array)
1692d3042a70SBarry Smith {
1693d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1694d3042a70SBarry Smith 
1695d3042a70SBarry Smith   PetscFunctionBegin;
16965ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
16975ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
16985ea7661aSPierre Jolivet   if (a->unplacedarray) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreArray() first");
1699d3042a70SBarry Smith   a->unplacedarray       = a->v;
1700d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1701d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1702637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1703ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1704c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1705ca15aa20SStefano Zampini #endif
1706d3042a70SBarry Smith   PetscFunctionReturn(0);
1707d3042a70SBarry Smith }
1708d3042a70SBarry Smith 
1709d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1710d3042a70SBarry Smith {
1711d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1712d3042a70SBarry Smith 
1713d3042a70SBarry Smith   PetscFunctionBegin;
17145ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
17155ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1716d3042a70SBarry Smith   a->v             = a->unplacedarray;
1717d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1718d3042a70SBarry Smith   a->unplacedarray = NULL;
1719ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1720c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1721ca15aa20SStefano Zampini #endif
1722d3042a70SBarry Smith   PetscFunctionReturn(0);
1723d3042a70SBarry Smith }
1724d3042a70SBarry Smith 
1725d5ea218eSStefano Zampini static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A,const PetscScalar *array)
1726d5ea218eSStefano Zampini {
1727d5ea218eSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1728d5ea218eSStefano Zampini   PetscErrorCode ierr;
1729d5ea218eSStefano Zampini 
1730d5ea218eSStefano Zampini   PetscFunctionBegin;
17315ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
17325ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1733d5ea218eSStefano Zampini   if (!a->user_alloc) { ierr = PetscFree(a->v);CHKERRQ(ierr); }
1734d5ea218eSStefano Zampini   a->v           = (PetscScalar*) array;
1735d5ea218eSStefano Zampini   a->user_alloc  = PETSC_FALSE;
1736d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1737d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1738d5ea218eSStefano Zampini #endif
1739d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1740d5ea218eSStefano Zampini }
1741d5ea218eSStefano Zampini 
1742ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1743289bc588SBarry Smith {
1744ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1745dfbe8321SBarry Smith   PetscErrorCode ierr;
174690f02eecSBarry Smith 
17473a40ed3dSBarry Smith   PetscFunctionBegin;
1748aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1749d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1750a5a9c739SBarry Smith #endif
17514396437dSToby Isaac   ierr = VecDestroy(&(l->qrrhs));CHKERRQ(ierr);
17524905a7bcSToby Isaac   ierr = PetscFree(l->tau);CHKERRQ(ierr);
175305b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1754a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1755abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
17566857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1757637a0070SStefano Zampini   if (!l->unplaced_user_alloc) {ierr = PetscFree(l->unplacedarray);CHKERRQ(ierr);}
17585ea7661aSPierre Jolivet   if (l->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
17595ea7661aSPierre Jolivet   if (l->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
17606947451fSStefano Zampini   ierr = VecDestroy(&l->cvec);CHKERRQ(ierr);
17615ea7661aSPierre Jolivet   ierr = MatDestroy(&l->cmat);CHKERRQ(ierr);
1762bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1763dbd8c25aSHong Zhang 
1764f4259b30SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)mat,NULL);CHKERRQ(ierr);
17654905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatQRFactor_C",NULL);CHKERRQ(ierr);
176649a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1767ad16ce7aSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseSetLDA_C",NULL);CHKERRQ(ierr);
1768bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
176952c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
1770d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1771d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
1772d5ea218eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseReplaceArray_C",NULL);CHKERRQ(ierr);
177352c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL);CHKERRQ(ierr);
177452c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL);CHKERRQ(ierr);
17756947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayWrite_C",NULL);CHKERRQ(ierr);
17766947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayWrite_C",NULL);CHKERRQ(ierr);
17778baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
17788baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17798baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
17808baccfbdSHong Zhang #endif
1781d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
1782d24d4204SJose E. Roman   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_scalapack_C",NULL);CHKERRQ(ierr);
1783d24d4204SJose E. Roman #endif
17842bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17852bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL);CHKERRQ(ierr);
17864222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL);CHKERRQ(ierr);
17874222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL);CHKERRQ(ierr);
17882bf066beSStefano Zampini #endif
1789bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
17904222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
17914222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL);CHKERRQ(ierr);
17924222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
17934222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
179452c5f739Sprj- 
179586aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
179686aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
17976947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVec_C",NULL);CHKERRQ(ierr);
17986947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVec_C",NULL);CHKERRQ(ierr);
17996947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecRead_C",NULL);CHKERRQ(ierr);
18006947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecRead_C",NULL);CHKERRQ(ierr);
18016947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecWrite_C",NULL);CHKERRQ(ierr);
18026947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecWrite_C",NULL);CHKERRQ(ierr);
18035ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetSubMatrix_C",NULL);CHKERRQ(ierr);
18045ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreSubMatrix_C",NULL);CHKERRQ(ierr);
18053a40ed3dSBarry Smith   PetscFunctionReturn(0);
1806289bc588SBarry Smith }
1807289bc588SBarry Smith 
1808e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1809289bc588SBarry Smith {
1810c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
18116849ba73SBarry Smith   PetscErrorCode ierr;
18126536e3caSStefano Zampini   PetscInt       k,j,m = A->rmap->n, M = mat->lda, n = A->cmap->n;
181387828ca2SBarry Smith   PetscScalar    *v,tmp;
181448b35521SBarry Smith 
18153a40ed3dSBarry Smith   PetscFunctionBegin;
18166536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
18176536e3caSStefano Zampini     if (m == n) { /* in place transpose */
1818ca15aa20SStefano Zampini       ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1819d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1820289bc588SBarry Smith         for (k=0; k<j; k++) {
18211b807ce4Svictorle           tmp        = v[j + k*M];
18221b807ce4Svictorle           v[j + k*M] = v[k + j*M];
18231b807ce4Svictorle           v[k + j*M] = tmp;
1824289bc588SBarry Smith         }
1825289bc588SBarry Smith       }
1826ca15aa20SStefano Zampini       ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
18276536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
18286536e3caSStefano Zampini       PetscScalar *v2;
18296536e3caSStefano Zampini       PetscLayout tmplayout;
18306536e3caSStefano Zampini 
18316536e3caSStefano Zampini       ierr = PetscMalloc1((size_t)m*n,&v2);CHKERRQ(ierr);
18326536e3caSStefano Zampini       ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
18336536e3caSStefano Zampini       for (j=0; j<n; j++) {
18346536e3caSStefano Zampini         for (k=0; k<m; k++) v2[j + (size_t)k*n] = v[k + (size_t)j*M];
18356536e3caSStefano Zampini       }
18366536e3caSStefano Zampini       ierr = PetscArraycpy(v,v2,(size_t)m*n);CHKERRQ(ierr);
18376536e3caSStefano Zampini       ierr = PetscFree(v2);CHKERRQ(ierr);
18386536e3caSStefano Zampini       ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
18396536e3caSStefano Zampini       /* cleanup size dependent quantities */
18406536e3caSStefano Zampini       ierr = VecDestroy(&mat->cvec);CHKERRQ(ierr);
18416536e3caSStefano Zampini       ierr = MatDestroy(&mat->cmat);CHKERRQ(ierr);
18426536e3caSStefano Zampini       ierr = PetscFree(mat->pivots);CHKERRQ(ierr);
18436536e3caSStefano Zampini       ierr = PetscFree(mat->fwork);CHKERRQ(ierr);
18446536e3caSStefano Zampini       ierr = MatDestroy(&mat->ptapwork);CHKERRQ(ierr);
18456536e3caSStefano Zampini       /* swap row/col layouts */
18466536e3caSStefano Zampini       mat->lda  = n;
18476536e3caSStefano Zampini       tmplayout = A->rmap;
18486536e3caSStefano Zampini       A->rmap   = A->cmap;
18496536e3caSStefano Zampini       A->cmap   = tmplayout;
18506536e3caSStefano Zampini     }
18513a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1852d3e5ee88SLois Curfman McInnes     Mat          tmat;
1853ec8511deSBarry Smith     Mat_SeqDense *tmatd;
185487828ca2SBarry Smith     PetscScalar  *v2;
1855af36a384SStefano Zampini     PetscInt     M2;
1856ea709b57SSatish Balay 
18576536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
1858ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1859d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
18607adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
18610298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1862ca15aa20SStefano Zampini     } else tmat = *matout;
1863ca15aa20SStefano Zampini 
1864ca15aa20SStefano Zampini     ierr  = MatDenseGetArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
1865ca15aa20SStefano Zampini     ierr  = MatDenseGetArray(tmat,&v2);CHKERRQ(ierr);
1866ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1867ca15aa20SStefano Zampini     M2    = tmatd->lda;
1868d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1869af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1870d3e5ee88SLois Curfman McInnes     }
1871ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(tmat,&v2);CHKERRQ(ierr);
1872ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
18736d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18746d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18756536e3caSStefano Zampini     *matout = tmat;
187648b35521SBarry Smith   }
18773a40ed3dSBarry Smith   PetscFunctionReturn(0);
1878289bc588SBarry Smith }
1879289bc588SBarry Smith 
1880e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1881289bc588SBarry Smith {
1882c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1883c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1884ca15aa20SStefano Zampini   PetscInt          i;
1885ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
1886ca15aa20SStefano Zampini   PetscErrorCode    ierr;
18879ea5d5aeSSatish Balay 
18883a40ed3dSBarry Smith   PetscFunctionBegin;
1889d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1890d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1891ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A1,&v1);CHKERRQ(ierr);
1892ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A2,&v2);CHKERRQ(ierr);
1893ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
1894ca15aa20SStefano Zampini     ierr = PetscArraycmp(v1,v2,A1->rmap->n,flg);CHKERRQ(ierr);
1895ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1896ca15aa20SStefano Zampini     v1 += mat1->lda;
1897ca15aa20SStefano Zampini     v2 += mat2->lda;
18981b807ce4Svictorle   }
1899ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A1,&v1);CHKERRQ(ierr);
1900ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A2,&v2);CHKERRQ(ierr);
190177c4ece6SBarry Smith   *flg = PETSC_TRUE;
19023a40ed3dSBarry Smith   PetscFunctionReturn(0);
1903289bc588SBarry Smith }
1904289bc588SBarry Smith 
1905e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1906289bc588SBarry Smith {
1907c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
190813f74950SBarry Smith   PetscInt          i,n,len;
1909ca15aa20SStefano Zampini   PetscScalar       *x;
1910ca15aa20SStefano Zampini   const PetscScalar *vv;
1911ca15aa20SStefano Zampini   PetscErrorCode    ierr;
191244cd7ae7SLois Curfman McInnes 
19133a40ed3dSBarry Smith   PetscFunctionBegin;
19147a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
19151ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1916d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1917ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1918e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
191944cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1920ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1921289bc588SBarry Smith   }
1922ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
19231ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
19243a40ed3dSBarry Smith   PetscFunctionReturn(0);
1925289bc588SBarry Smith }
1926289bc588SBarry Smith 
1927e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1928289bc588SBarry Smith {
1929c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1930f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1931ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1932dfbe8321SBarry Smith   PetscErrorCode    ierr;
1933d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
193455659b69SBarry Smith 
19353a40ed3dSBarry Smith   PetscFunctionBegin;
1936ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&vv);CHKERRQ(ierr);
193728988994SBarry Smith   if (ll) {
19387a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1939f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1940e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1941da3a660dSBarry Smith     for (i=0; i<m; i++) {
1942da3a660dSBarry Smith       x = l[i];
1943ca15aa20SStefano Zampini       v = vv + i;
1944b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1945da3a660dSBarry Smith     }
1946f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1947eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1948da3a660dSBarry Smith   }
194928988994SBarry Smith   if (rr) {
19507a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1951f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1952e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1953da3a660dSBarry Smith     for (i=0; i<n; i++) {
1954da3a660dSBarry Smith       x = r[i];
1955ca15aa20SStefano Zampini       v = vv + i*mat->lda;
19562205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1957da3a660dSBarry Smith     }
1958f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1959eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1960da3a660dSBarry Smith   }
1961ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&vv);CHKERRQ(ierr);
19623a40ed3dSBarry Smith   PetscFunctionReturn(0);
1963289bc588SBarry Smith }
1964289bc588SBarry Smith 
1965ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1966289bc588SBarry Smith {
1967c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1968ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1969329f5518SBarry Smith   PetscReal         sum  = 0.0;
1970d0f46423SBarry Smith   PetscInt          lda  =mat->lda,m=A->rmap->n,i,j;
1971efee365bSSatish Balay   PetscErrorCode    ierr;
197255659b69SBarry Smith 
19733a40ed3dSBarry Smith   PetscFunctionBegin;
1974ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
1975ca15aa20SStefano Zampini   v    = vv;
1976289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1977a5ce6ee0Svictorle     if (lda>m) {
1978d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1979ca15aa20SStefano Zampini         v = vv+j*lda;
1980a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1981a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1982a5ce6ee0Svictorle         }
1983a5ce6ee0Svictorle       }
1984a5ce6ee0Svictorle     } else {
1985570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1986570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
198773cf7048SBarry Smith       PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&cnt,v,&one));
1988570b7f6dSBarry Smith     }
1989570b7f6dSBarry Smith #else
1990d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1991329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1992289bc588SBarry Smith       }
1993a5ce6ee0Svictorle     }
19948f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1995570b7f6dSBarry Smith #endif
1996dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
19973a40ed3dSBarry Smith   } else if (type == NORM_1) {
1998064f8208SBarry Smith     *nrm = 0.0;
1999d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2000ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
2001289bc588SBarry Smith       sum = 0.0;
2002d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
200333a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
2004289bc588SBarry Smith       }
2005064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
2006289bc588SBarry Smith     }
2007eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
20083a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2009064f8208SBarry Smith     *nrm = 0.0;
2010d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
2011ca15aa20SStefano Zampini       v   = vv + j;
2012289bc588SBarry Smith       sum = 0.0;
2013d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
20141b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
2015289bc588SBarry Smith       }
2016064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
2017289bc588SBarry Smith     }
2018eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
2019e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
2020ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
20213a40ed3dSBarry Smith   PetscFunctionReturn(0);
2022289bc588SBarry Smith }
2023289bc588SBarry Smith 
2024e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
2025289bc588SBarry Smith {
2026c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
202763ba0a88SBarry Smith   PetscErrorCode ierr;
202867e560aaSBarry Smith 
20293a40ed3dSBarry Smith   PetscFunctionBegin;
2030b5a2b587SKris Buschelman   switch (op) {
2031b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
20324e0d8c25SBarry Smith     aij->roworiented = flg;
2033b5a2b587SKris Buschelman     break;
2034512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
2035b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
20363971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
20378c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
203813fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
2039b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
2040b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
20410f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
20425021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
2043071fcb05SBarry Smith   case MAT_SORTED_FULL:
20445021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
20455021d80fSJed Brown     break;
20465021d80fSJed Brown   case MAT_SPD:
204777e54ba9SKris Buschelman   case MAT_SYMMETRIC:
204877e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
20499a4540c5SBarry Smith   case MAT_HERMITIAN:
20509a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
20515021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
205277e54ba9SKris Buschelman     break;
2053b5a2b587SKris Buschelman   default:
2054e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
20553a40ed3dSBarry Smith   }
20563a40ed3dSBarry Smith   PetscFunctionReturn(0);
2057289bc588SBarry Smith }
2058289bc588SBarry Smith 
20593d8925e7SStefano Zampini PetscErrorCode MatZeroEntries_SeqDense(Mat A)
20606f0a148fSBarry Smith {
2061ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
20626849ba73SBarry Smith   PetscErrorCode ierr;
20633d8925e7SStefano Zampini   PetscInt       lda=l->lda,m=A->rmap->n,n=A->cmap->n,j;
2064ca15aa20SStefano Zampini   PetscScalar    *v;
20653a40ed3dSBarry Smith 
20663a40ed3dSBarry Smith   PetscFunctionBegin;
20673d8925e7SStefano Zampini   ierr = MatDenseGetArrayWrite(A,&v);CHKERRQ(ierr);
2068a5ce6ee0Svictorle   if (lda>m) {
20693d8925e7SStefano Zampini     for (j=0; j<n; j++) {
2070ca15aa20SStefano Zampini       ierr = PetscArrayzero(v+j*lda,m);CHKERRQ(ierr);
2071a5ce6ee0Svictorle     }
2072a5ce6ee0Svictorle   } else {
20733d8925e7SStefano Zampini     ierr = PetscArrayzero(v,PetscInt64Mult(m,n));CHKERRQ(ierr);
2074a5ce6ee0Svictorle   }
20753d8925e7SStefano Zampini   ierr = MatDenseRestoreArrayWrite(A,&v);CHKERRQ(ierr);
20763a40ed3dSBarry Smith   PetscFunctionReturn(0);
20776f0a148fSBarry Smith }
20786f0a148fSBarry Smith 
2079e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
20806f0a148fSBarry Smith {
208197b48c8fSBarry Smith   PetscErrorCode    ierr;
2082ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
2083b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
2084ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
208597b48c8fSBarry Smith   const PetscScalar *xx;
208655659b69SBarry Smith 
20873a40ed3dSBarry Smith   PetscFunctionBegin;
208876bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2089b9679d65SBarry Smith     for (i=0; i<N; i++) {
2090b9679d65SBarry Smith       if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
2091b9679d65SBarry 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);
2092b9679d65SBarry Smith     }
209376bd3646SJed Brown   }
2094ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
2095b9679d65SBarry Smith 
209697b48c8fSBarry Smith   /* fix right hand side if needed */
209797b48c8fSBarry Smith   if (x && b) {
209897b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
209997b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
21002205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
210197b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
210297b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
210397b48c8fSBarry Smith   }
210497b48c8fSBarry Smith 
2105ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
21066f0a148fSBarry Smith   for (i=0; i<N; i++) {
2107ca15aa20SStefano Zampini     slot = v + rows[i];
2108b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
21096f0a148fSBarry Smith   }
2110f4df32b1SMatthew Knepley   if (diag != 0.0) {
2111b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
21126f0a148fSBarry Smith     for (i=0; i<N; i++) {
2113ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
2114f4df32b1SMatthew Knepley       *slot = diag;
21156f0a148fSBarry Smith     }
21166f0a148fSBarry Smith   }
2117ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
21183a40ed3dSBarry Smith   PetscFunctionReturn(0);
21196f0a148fSBarry Smith }
2120557bce09SLois Curfman McInnes 
212149a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
212249a6ff4bSBarry Smith {
212349a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
212449a6ff4bSBarry Smith 
212549a6ff4bSBarry Smith   PetscFunctionBegin;
212649a6ff4bSBarry Smith   *lda = mat->lda;
212749a6ff4bSBarry Smith   PetscFunctionReturn(0);
212849a6ff4bSBarry Smith }
212949a6ff4bSBarry Smith 
2130637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array)
213164e87e97SBarry Smith {
2132c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
21333a40ed3dSBarry Smith 
21343a40ed3dSBarry Smith   PetscFunctionBegin;
2135616b8fbbSStefano Zampini   if (mat->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
213664e87e97SBarry Smith   *array = mat->v;
21373a40ed3dSBarry Smith   PetscFunctionReturn(0);
213864e87e97SBarry Smith }
21390754003eSLois Curfman McInnes 
2140637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array)
2141ff14e315SSatish Balay {
21423a40ed3dSBarry Smith   PetscFunctionBegin;
2143637a0070SStefano Zampini   *array = NULL;
21443a40ed3dSBarry Smith   PetscFunctionReturn(0);
2145ff14e315SSatish Balay }
21460754003eSLois Curfman McInnes 
2147dec5eb66SMatthew G Knepley /*@C
214849a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
214949a6ff4bSBarry Smith 
2150ad16ce7aSStefano Zampini    Not collective
215149a6ff4bSBarry Smith 
215249a6ff4bSBarry Smith    Input Parameter:
215349a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
215449a6ff4bSBarry Smith 
215549a6ff4bSBarry Smith    Output Parameter:
215649a6ff4bSBarry Smith .   lda - the leading dimension
215749a6ff4bSBarry Smith 
215849a6ff4bSBarry Smith    Level: intermediate
215949a6ff4bSBarry Smith 
2160ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseSetLDA()
216149a6ff4bSBarry Smith @*/
216249a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
216349a6ff4bSBarry Smith {
216449a6ff4bSBarry Smith   PetscErrorCode ierr;
216549a6ff4bSBarry Smith 
216649a6ff4bSBarry Smith   PetscFunctionBegin;
2167d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2168d5ea218eSStefano Zampini   PetscValidPointer(lda,2);
216949a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
217049a6ff4bSBarry Smith   PetscFunctionReturn(0);
217149a6ff4bSBarry Smith }
217249a6ff4bSBarry Smith 
217349a6ff4bSBarry Smith /*@C
2174ad16ce7aSStefano Zampini    MatDenseSetLDA - Sets the leading dimension of the array used by the dense matrix
2175ad16ce7aSStefano Zampini 
2176ad16ce7aSStefano Zampini    Not collective
2177ad16ce7aSStefano Zampini 
2178d8d19677SJose E. Roman    Input Parameters:
2179ad16ce7aSStefano Zampini +  mat - a MATSEQDENSE or MATMPIDENSE matrix
2180ad16ce7aSStefano Zampini -  lda - the leading dimension
2181ad16ce7aSStefano Zampini 
2182ad16ce7aSStefano Zampini    Level: intermediate
2183ad16ce7aSStefano Zampini 
2184ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetLDA()
2185ad16ce7aSStefano Zampini @*/
2186ad16ce7aSStefano Zampini PetscErrorCode  MatDenseSetLDA(Mat A,PetscInt lda)
2187ad16ce7aSStefano Zampini {
2188ad16ce7aSStefano Zampini   PetscErrorCode ierr;
2189ad16ce7aSStefano Zampini 
2190ad16ce7aSStefano Zampini   PetscFunctionBegin;
2191ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2192ad16ce7aSStefano Zampini   ierr = PetscTryMethod(A,"MatDenseSetLDA_C",(Mat,PetscInt),(A,lda));CHKERRQ(ierr);
2193ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2194ad16ce7aSStefano Zampini }
2195ad16ce7aSStefano Zampini 
2196ad16ce7aSStefano Zampini /*@C
21976947451fSStefano Zampini    MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored
219873a71a0fSBarry Smith 
21998572280aSBarry Smith    Logically Collective on Mat
220073a71a0fSBarry Smith 
220173a71a0fSBarry Smith    Input Parameter:
22026947451fSStefano Zampini .  mat - a dense matrix
220373a71a0fSBarry Smith 
220473a71a0fSBarry Smith    Output Parameter:
220573a71a0fSBarry Smith .   array - pointer to the data
220673a71a0fSBarry Smith 
220773a71a0fSBarry Smith    Level: intermediate
220873a71a0fSBarry Smith 
22096947451fSStefano Zampini .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
221073a71a0fSBarry Smith @*/
22118c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
221273a71a0fSBarry Smith {
221373a71a0fSBarry Smith   PetscErrorCode ierr;
221473a71a0fSBarry Smith 
221573a71a0fSBarry Smith   PetscFunctionBegin;
2216d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2217d5ea218eSStefano Zampini   PetscValidPointer(array,2);
22188c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
221973a71a0fSBarry Smith   PetscFunctionReturn(0);
222073a71a0fSBarry Smith }
222173a71a0fSBarry Smith 
2222dec5eb66SMatthew G Knepley /*@C
2223579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
222473a71a0fSBarry Smith 
22258572280aSBarry Smith    Logically Collective on Mat
22268572280aSBarry Smith 
22278572280aSBarry Smith    Input Parameters:
22286947451fSStefano Zampini +  mat - a dense matrix
2229a2b725a8SWilliam Gropp -  array - pointer to the data
22308572280aSBarry Smith 
22318572280aSBarry Smith    Level: intermediate
22328572280aSBarry Smith 
22336947451fSStefano Zampini .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
22348572280aSBarry Smith @*/
22358572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
22368572280aSBarry Smith {
22378572280aSBarry Smith   PetscErrorCode ierr;
22388572280aSBarry Smith 
22398572280aSBarry Smith   PetscFunctionBegin;
2240d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2241d5ea218eSStefano Zampini   PetscValidPointer(array,2);
22428572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
22438572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
2244637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
2245637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2246637a0070SStefano Zampini #endif
22478572280aSBarry Smith   PetscFunctionReturn(0);
22488572280aSBarry Smith }
22498572280aSBarry Smith 
22508572280aSBarry Smith /*@C
22516947451fSStefano Zampini    MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored
22528572280aSBarry Smith 
22538572280aSBarry Smith    Not Collective
22548572280aSBarry Smith 
22558572280aSBarry Smith    Input Parameter:
22566947451fSStefano Zampini .  mat - a dense matrix
22578572280aSBarry Smith 
22588572280aSBarry Smith    Output Parameter:
22598572280aSBarry Smith .   array - pointer to the data
22608572280aSBarry Smith 
22618572280aSBarry Smith    Level: intermediate
22628572280aSBarry Smith 
22636947451fSStefano Zampini .seealso: MatDenseRestoreArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
22648572280aSBarry Smith @*/
22658572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
22668572280aSBarry Smith {
22678572280aSBarry Smith   PetscErrorCode ierr;
22688572280aSBarry Smith 
22698572280aSBarry Smith   PetscFunctionBegin;
2270d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2271d5ea218eSStefano Zampini   PetscValidPointer(array,2);
22728572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
22738572280aSBarry Smith   PetscFunctionReturn(0);
22748572280aSBarry Smith }
22758572280aSBarry Smith 
22768572280aSBarry Smith /*@C
22776947451fSStefano Zampini    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead()
22788572280aSBarry Smith 
227973a71a0fSBarry Smith    Not Collective
228073a71a0fSBarry Smith 
228173a71a0fSBarry Smith    Input Parameters:
22826947451fSStefano Zampini +  mat - a dense matrix
2283a2b725a8SWilliam Gropp -  array - pointer to the data
228473a71a0fSBarry Smith 
228573a71a0fSBarry Smith    Level: intermediate
228673a71a0fSBarry Smith 
22876947451fSStefano Zampini .seealso: MatDenseGetArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
228873a71a0fSBarry Smith @*/
22898572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
229073a71a0fSBarry Smith {
229173a71a0fSBarry Smith   PetscErrorCode ierr;
229273a71a0fSBarry Smith 
229373a71a0fSBarry Smith   PetscFunctionBegin;
2294d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2295d5ea218eSStefano Zampini   PetscValidPointer(array,2);
22968572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
229773a71a0fSBarry Smith   PetscFunctionReturn(0);
229873a71a0fSBarry Smith }
229973a71a0fSBarry Smith 
23006947451fSStefano Zampini /*@C
23016947451fSStefano Zampini    MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored
23026947451fSStefano Zampini 
23036947451fSStefano Zampini    Not Collective
23046947451fSStefano Zampini 
23056947451fSStefano Zampini    Input Parameter:
23066947451fSStefano Zampini .  mat - a dense matrix
23076947451fSStefano Zampini 
23086947451fSStefano Zampini    Output Parameter:
23096947451fSStefano Zampini .   array - pointer to the data
23106947451fSStefano Zampini 
23116947451fSStefano Zampini    Level: intermediate
23126947451fSStefano Zampini 
23136947451fSStefano Zampini .seealso: MatDenseRestoreArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
23146947451fSStefano Zampini @*/
23156947451fSStefano Zampini PetscErrorCode  MatDenseGetArrayWrite(Mat A,PetscScalar **array)
23166947451fSStefano Zampini {
23176947451fSStefano Zampini   PetscErrorCode ierr;
23186947451fSStefano Zampini 
23196947451fSStefano Zampini   PetscFunctionBegin;
2320d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2321d5ea218eSStefano Zampini   PetscValidPointer(array,2);
23226947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
23236947451fSStefano Zampini   PetscFunctionReturn(0);
23246947451fSStefano Zampini }
23256947451fSStefano Zampini 
23266947451fSStefano Zampini /*@C
23276947451fSStefano Zampini    MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite()
23286947451fSStefano Zampini 
23296947451fSStefano Zampini    Not Collective
23306947451fSStefano Zampini 
23316947451fSStefano Zampini    Input Parameters:
23326947451fSStefano Zampini +  mat - a dense matrix
23336947451fSStefano Zampini -  array - pointer to the data
23346947451fSStefano Zampini 
23356947451fSStefano Zampini    Level: intermediate
23366947451fSStefano Zampini 
23376947451fSStefano Zampini .seealso: MatDenseGetArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
23386947451fSStefano Zampini @*/
23396947451fSStefano Zampini PetscErrorCode  MatDenseRestoreArrayWrite(Mat A,PetscScalar **array)
23406947451fSStefano Zampini {
23416947451fSStefano Zampini   PetscErrorCode ierr;
23426947451fSStefano Zampini 
23436947451fSStefano Zampini   PetscFunctionBegin;
2344d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2345d5ea218eSStefano Zampini   PetscValidPointer(array,2);
23466947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
23476947451fSStefano Zampini   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
23486947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
23496947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
23506947451fSStefano Zampini #endif
23516947451fSStefano Zampini   PetscFunctionReturn(0);
23526947451fSStefano Zampini }
23536947451fSStefano Zampini 
2354023c16fcSToby Isaac static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,MatReuse scall,Mat *B)
23550754003eSLois Curfman McInnes {
2356c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
23576849ba73SBarry Smith   PetscErrorCode ierr;
2358bf5a80bcSToby Isaac   PetscInt       i,j,nrows,ncols,ldb;
23595d0c19d7SBarry Smith   const PetscInt *irow,*icol;
236087828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
23610754003eSLois Curfman McInnes   Mat            newmat;
23620754003eSLois Curfman McInnes 
23633a40ed3dSBarry Smith   PetscFunctionBegin;
236478b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
236578b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
2366e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2367e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
23680754003eSLois Curfman McInnes 
2369182d2002SSatish Balay   /* Check submatrixcall */
2370182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
237113f74950SBarry Smith     PetscInt n_cols,n_rows;
2372182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
237321a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2374f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
2375c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
237621a2c019SBarry Smith     }
2377182d2002SSatish Balay     newmat = *B;
2378182d2002SSatish Balay   } else {
23790754003eSLois Curfman McInnes     /* Create and fill new matrix */
2380ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
2381f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
23827adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
23830298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
2384182d2002SSatish Balay   }
2385182d2002SSatish Balay 
2386182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
2387ca15aa20SStefano Zampini   ierr = MatDenseGetArray(newmat,&bv);CHKERRQ(ierr);
2388bf5a80bcSToby Isaac   ierr = MatDenseGetLDA(newmat,&ldb);CHKERRQ(ierr);
2389182d2002SSatish Balay   for (i=0; i<ncols; i++) {
23906de62eeeSBarry Smith     av = v + mat->lda*icol[i];
2391ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
2392bf5a80bcSToby Isaac     bv += ldb;
23930754003eSLois Curfman McInnes   }
2394ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(newmat,&bv);CHKERRQ(ierr);
2395182d2002SSatish Balay 
2396182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
23976d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
23986d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
23990754003eSLois Curfman McInnes 
24000754003eSLois Curfman McInnes   /* Free work space */
240178b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
240278b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2403182d2002SSatish Balay   *B   = newmat;
24043a40ed3dSBarry Smith   PetscFunctionReturn(0);
24050754003eSLois Curfman McInnes }
24060754003eSLois Curfman McInnes 
24077dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2408905e6a2fSBarry Smith {
24096849ba73SBarry Smith   PetscErrorCode ierr;
241013f74950SBarry Smith   PetscInt       i;
2411905e6a2fSBarry Smith 
24123a40ed3dSBarry Smith   PetscFunctionBegin;
2413905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
24143741e84bSPierre Jolivet     ierr = PetscCalloc1(n,B);CHKERRQ(ierr);
2415905e6a2fSBarry Smith   }
2416905e6a2fSBarry Smith 
2417905e6a2fSBarry Smith   for (i=0; i<n; i++) {
2418023c16fcSToby Isaac     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],scall,&(*B)[i]);CHKERRQ(ierr);
2419905e6a2fSBarry Smith   }
24203a40ed3dSBarry Smith   PetscFunctionReturn(0);
2421905e6a2fSBarry Smith }
2422905e6a2fSBarry Smith 
2423e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2424c0aa2d19SHong Zhang {
2425c0aa2d19SHong Zhang   PetscFunctionBegin;
2426c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2427c0aa2d19SHong Zhang }
2428c0aa2d19SHong Zhang 
2429e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2430c0aa2d19SHong Zhang {
2431c0aa2d19SHong Zhang   PetscFunctionBegin;
2432c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2433c0aa2d19SHong Zhang }
2434c0aa2d19SHong Zhang 
2435a76f77c3SStefano Zampini PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
24364b0e389bSBarry Smith {
24374b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
24386849ba73SBarry Smith   PetscErrorCode    ierr;
2439ca15aa20SStefano Zampini   const PetscScalar *va;
2440ca15aa20SStefano Zampini   PetscScalar       *vb;
2441d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
24423a40ed3dSBarry Smith 
24433a40ed3dSBarry Smith   PetscFunctionBegin;
244433f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
244533f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
2446cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
24473a40ed3dSBarry Smith     PetscFunctionReturn(0);
24483a40ed3dSBarry Smith   }
2449e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
2450ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&va);CHKERRQ(ierr);
2451ca15aa20SStefano Zampini   ierr = MatDenseGetArray(B,&vb);CHKERRQ(ierr);
2452a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
24530dbb7854Svictorle     for (j=0; j<n; j++) {
2454ca15aa20SStefano Zampini       ierr = PetscArraycpy(vb+j*lda2,va+j*lda1,m);CHKERRQ(ierr);
2455a5ce6ee0Svictorle     }
2456a5ce6ee0Svictorle   } else {
2457ca15aa20SStefano Zampini     ierr = PetscArraycpy(vb,va,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2458a5ce6ee0Svictorle   }
2459ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(B,&vb);CHKERRQ(ierr);
2460ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&va);CHKERRQ(ierr);
2461ca15aa20SStefano Zampini   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2462ca15aa20SStefano Zampini   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2463273d9f13SBarry Smith   PetscFunctionReturn(0);
2464273d9f13SBarry Smith }
2465273d9f13SBarry Smith 
2466e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
2467273d9f13SBarry Smith {
2468dfbe8321SBarry Smith   PetscErrorCode ierr;
2469273d9f13SBarry Smith 
2470273d9f13SBarry Smith   PetscFunctionBegin;
247118992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
247218992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
247318992e5dSStefano Zampini   if (!A->preallocated) {
2474f4259b30SLisandro Dalcin     ierr = MatSeqDenseSetPreallocation(A,NULL);CHKERRQ(ierr);
247518992e5dSStefano Zampini   }
24763a40ed3dSBarry Smith   PetscFunctionReturn(0);
24774b0e389bSBarry Smith }
24784b0e389bSBarry Smith 
2479ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2480ba337c44SJed Brown {
24814396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
2482ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
24834396437dSToby Isaac   PetscInt       min = PetscMin(A->rmap->n,A->cmap->n);
2484ca15aa20SStefano Zampini   PetscScalar    *aa;
2485ca15aa20SStefano Zampini   PetscErrorCode ierr;
2486ba337c44SJed Brown 
2487ba337c44SJed Brown   PetscFunctionBegin;
2488ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2489ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2490ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
24914396437dSToby Isaac   if (mat->tau) for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2492ba337c44SJed Brown   PetscFunctionReturn(0);
2493ba337c44SJed Brown }
2494ba337c44SJed Brown 
2495ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2496ba337c44SJed Brown {
2497ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2498ca15aa20SStefano Zampini   PetscScalar    *aa;
2499ca15aa20SStefano Zampini   PetscErrorCode ierr;
2500ba337c44SJed Brown 
2501ba337c44SJed Brown   PetscFunctionBegin;
2502ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2503ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2504ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2505ba337c44SJed Brown   PetscFunctionReturn(0);
2506ba337c44SJed Brown }
2507ba337c44SJed Brown 
2508ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_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] = PetscImaginaryPart(aa[i]);
2517ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2518ba337c44SJed Brown   PetscFunctionReturn(0);
2519ba337c44SJed Brown }
2520284134d9SBarry Smith 
2521a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
25224222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2523a9fe9ddaSSatish Balay {
2524ee16a9a1SHong Zhang   PetscErrorCode ierr;
2525d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
25267a3c3d58SStefano Zampini   PetscBool      cisdense;
2527a9fe9ddaSSatish Balay 
2528ee16a9a1SHong Zhang   PetscFunctionBegin;
25294222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
25307a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
25317a3c3d58SStefano Zampini   if (!cisdense) {
25327a3c3d58SStefano Zampini     PetscBool flg;
25337a3c3d58SStefano Zampini 
2534ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
25354222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
25367a3c3d58SStefano Zampini   }
253718992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2538ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2539ee16a9a1SHong Zhang }
2540a9fe9ddaSSatish Balay 
2541a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2542a9fe9ddaSSatish Balay {
25436718818eSStefano Zampini   Mat_SeqDense       *a=(Mat_SeqDense*)A->data,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
25440805154bSBarry Smith   PetscBLASInt       m,n,k;
2545ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2546ca15aa20SStefano Zampini   PetscScalar       *cv;
2547a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2548c2916339SPierre Jolivet   PetscErrorCode    ierr;
2549a9fe9ddaSSatish Balay 
2550a9fe9ddaSSatish Balay   PetscFunctionBegin;
25518208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
25528208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2553c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
255449d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
2555ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
2556ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
25576718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
2558ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
2559ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2560ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
2561ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
25626718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2563a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2564a9fe9ddaSSatish Balay }
2565a9fe9ddaSSatish Balay 
25664222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
256769f65d41SStefano Zampini {
256869f65d41SStefano Zampini   PetscErrorCode ierr;
256969f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
25707a3c3d58SStefano Zampini   PetscBool      cisdense;
257169f65d41SStefano Zampini 
257269f65d41SStefano Zampini   PetscFunctionBegin;
25734222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
25747a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
25757a3c3d58SStefano Zampini   if (!cisdense) {
25767a3c3d58SStefano Zampini     PetscBool flg;
25777a3c3d58SStefano Zampini 
2578ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
25794222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
25807a3c3d58SStefano Zampini   }
258118992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
258269f65d41SStefano Zampini   PetscFunctionReturn(0);
258369f65d41SStefano Zampini }
258469f65d41SStefano Zampini 
258569f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
258669f65d41SStefano Zampini {
258769f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
258869f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
258969f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
25906718818eSStefano Zampini   const PetscScalar *av,*bv;
25916718818eSStefano Zampini   PetscScalar       *cv;
259269f65d41SStefano Zampini   PetscBLASInt      m,n,k;
259369f65d41SStefano Zampini   PetscScalar       _DOne=1.0,_DZero=0.0;
259469f65d41SStefano Zampini   PetscErrorCode    ierr;
259569f65d41SStefano Zampini 
259669f65d41SStefano Zampini   PetscFunctionBegin;
259749d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
259849d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
259969f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
260049d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
26016718818eSStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
26026718818eSStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
26036718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
26046718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
26056718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
26066718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
26076718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2608ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
260969f65d41SStefano Zampini   PetscFunctionReturn(0);
261069f65d41SStefano Zampini }
261169f65d41SStefano Zampini 
26124222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2613a9fe9ddaSSatish Balay {
2614ee16a9a1SHong Zhang   PetscErrorCode ierr;
2615d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
26167a3c3d58SStefano Zampini   PetscBool      cisdense;
2617a9fe9ddaSSatish Balay 
2618ee16a9a1SHong Zhang   PetscFunctionBegin;
26194222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
26207a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
26217a3c3d58SStefano Zampini   if (!cisdense) {
26227a3c3d58SStefano Zampini     PetscBool flg;
26237a3c3d58SStefano Zampini 
2624ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
26254222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
26267a3c3d58SStefano Zampini   }
262718992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2628ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2629ee16a9a1SHong Zhang }
2630a9fe9ddaSSatish Balay 
263175648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2632a9fe9ddaSSatish Balay {
2633a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2634a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
2635a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
26366718818eSStefano Zampini   const PetscScalar *av,*bv;
26376718818eSStefano Zampini   PetscScalar       *cv;
26380805154bSBarry Smith   PetscBLASInt      m,n,k;
2639a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2640c5df96a5SBarry Smith   PetscErrorCode    ierr;
2641a9fe9ddaSSatish Balay 
2642a9fe9ddaSSatish Balay   PetscFunctionBegin;
26438208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
26448208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2645c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
264649d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
26476718818eSStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
26486718818eSStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
26496718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
26506718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
26516718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
26526718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
26536718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2654ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2655a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2656a9fe9ddaSSatish Balay }
2657985db425SBarry Smith 
26584222ddf1SHong Zhang /* ----------------------------------------------- */
26594222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
26604222ddf1SHong Zhang {
26614222ddf1SHong Zhang   PetscFunctionBegin;
26624222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
26634222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
26644222ddf1SHong Zhang   PetscFunctionReturn(0);
26654222ddf1SHong Zhang }
26664222ddf1SHong Zhang 
26674222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
26684222ddf1SHong Zhang {
26694222ddf1SHong Zhang   PetscFunctionBegin;
26704222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
26714222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
26724222ddf1SHong Zhang   PetscFunctionReturn(0);
26734222ddf1SHong Zhang }
26744222ddf1SHong Zhang 
26754222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
26764222ddf1SHong Zhang {
26774222ddf1SHong Zhang   PetscFunctionBegin;
26784222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
26794222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
26804222ddf1SHong Zhang   PetscFunctionReturn(0);
26814222ddf1SHong Zhang }
26824222ddf1SHong Zhang 
26834222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
26844222ddf1SHong Zhang {
26854222ddf1SHong Zhang   PetscErrorCode ierr;
26864222ddf1SHong Zhang   Mat_Product    *product = C->product;
26874222ddf1SHong Zhang 
26884222ddf1SHong Zhang   PetscFunctionBegin;
26894222ddf1SHong Zhang   switch (product->type) {
26904222ddf1SHong Zhang   case MATPRODUCT_AB:
26914222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AB(C);CHKERRQ(ierr);
26924222ddf1SHong Zhang     break;
26934222ddf1SHong Zhang   case MATPRODUCT_AtB:
26944222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AtB(C);CHKERRQ(ierr);
26954222ddf1SHong Zhang     break;
26964222ddf1SHong Zhang   case MATPRODUCT_ABt:
26974222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_ABt(C);CHKERRQ(ierr);
26984222ddf1SHong Zhang     break;
26996718818eSStefano Zampini   default:
27004222ddf1SHong Zhang     break;
27014222ddf1SHong Zhang   }
27024222ddf1SHong Zhang   PetscFunctionReturn(0);
27034222ddf1SHong Zhang }
27044222ddf1SHong Zhang /* ----------------------------------------------- */
27054222ddf1SHong Zhang 
2706e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2707985db425SBarry Smith {
2708985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2709985db425SBarry Smith   PetscErrorCode     ierr;
2710d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2711985db425SBarry Smith   PetscScalar        *x;
2712ca15aa20SStefano Zampini   const PetscScalar *aa;
2713985db425SBarry Smith 
2714985db425SBarry Smith   PetscFunctionBegin;
2715e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2716985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2717985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2718ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2719e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2720985db425SBarry Smith   for (i=0; i<m; i++) {
2721985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2722985db425SBarry Smith     for (j=1; j<n; j++) {
2723ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2724985db425SBarry Smith     }
2725985db425SBarry Smith   }
2726ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2727985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2728985db425SBarry Smith   PetscFunctionReturn(0);
2729985db425SBarry Smith }
2730985db425SBarry Smith 
2731e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2732985db425SBarry Smith {
2733985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2734985db425SBarry Smith   PetscErrorCode    ierr;
2735d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2736985db425SBarry Smith   PetscScalar       *x;
2737985db425SBarry Smith   PetscReal         atmp;
2738ca15aa20SStefano Zampini   const PetscScalar *aa;
2739985db425SBarry Smith 
2740985db425SBarry Smith   PetscFunctionBegin;
2741e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2742985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2743985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2744ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2745e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2746985db425SBarry Smith   for (i=0; i<m; i++) {
27479189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2748985db425SBarry Smith     for (j=1; j<n; j++) {
2749ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2750985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2751985db425SBarry Smith     }
2752985db425SBarry Smith   }
2753ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2754985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2755985db425SBarry Smith   PetscFunctionReturn(0);
2756985db425SBarry Smith }
2757985db425SBarry Smith 
2758e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2759985db425SBarry Smith {
2760985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2761985db425SBarry Smith   PetscErrorCode    ierr;
2762d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2763985db425SBarry Smith   PetscScalar       *x;
2764ca15aa20SStefano Zampini   const PetscScalar *aa;
2765985db425SBarry Smith 
2766985db425SBarry Smith   PetscFunctionBegin;
2767e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2768ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2769985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2770985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2771e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2772985db425SBarry Smith   for (i=0; i<m; i++) {
2773985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2774985db425SBarry Smith     for (j=1; j<n; j++) {
2775ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2776985db425SBarry Smith     }
2777985db425SBarry Smith   }
2778985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2779ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2780985db425SBarry Smith   PetscFunctionReturn(0);
2781985db425SBarry Smith }
2782985db425SBarry Smith 
2783637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
27848d0534beSBarry Smith {
27858d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
27868d0534beSBarry Smith   PetscErrorCode    ierr;
27878d0534beSBarry Smith   PetscScalar       *x;
2788ca15aa20SStefano Zampini   const PetscScalar *aa;
27898d0534beSBarry Smith 
27908d0534beSBarry Smith   PetscFunctionBegin;
2791e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2792ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
27938d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2794ca15aa20SStefano Zampini   ierr = PetscArraycpy(x,aa+col*a->lda,A->rmap->n);CHKERRQ(ierr);
27958d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2796ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
27978d0534beSBarry Smith   PetscFunctionReturn(0);
27988d0534beSBarry Smith }
27998d0534beSBarry Smith 
2800857cbf51SRichard Tran Mills PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A,PetscInt type,PetscReal *reductions)
28010716a85fSBarry Smith {
28020716a85fSBarry Smith   PetscErrorCode    ierr;
28030716a85fSBarry Smith   PetscInt          i,j,m,n;
28041683a169SBarry Smith   const PetscScalar *a;
28050716a85fSBarry Smith 
28060716a85fSBarry Smith   PetscFunctionBegin;
28070716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2808a873a8cdSSam Reynolds   ierr = PetscArrayzero(reductions,n);CHKERRQ(ierr);
28091683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&a);CHKERRQ(ierr);
2810857cbf51SRichard Tran Mills   if (type == NORM_2) {
28110716a85fSBarry Smith     for (i=0; i<n; i++) {
28120716a85fSBarry Smith       for (j=0; j<m; j++) {
2813a873a8cdSSam Reynolds         reductions[i] += PetscAbsScalar(a[j]*a[j]);
28140716a85fSBarry Smith       }
28150716a85fSBarry Smith       a += m;
28160716a85fSBarry Smith     }
2817857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
28180716a85fSBarry Smith     for (i=0; i<n; i++) {
28190716a85fSBarry Smith       for (j=0; j<m; j++) {
2820a873a8cdSSam Reynolds         reductions[i] += PetscAbsScalar(a[j]);
28210716a85fSBarry Smith       }
28220716a85fSBarry Smith       a += m;
28230716a85fSBarry Smith     }
2824857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
28250716a85fSBarry Smith     for (i=0; i<n; i++) {
28260716a85fSBarry Smith       for (j=0; j<m; j++) {
2827a873a8cdSSam Reynolds         reductions[i] = PetscMax(PetscAbsScalar(a[j]),reductions[i]);
28280716a85fSBarry Smith       }
28290716a85fSBarry Smith       a += m;
28300716a85fSBarry Smith     }
2831857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
2832a873a8cdSSam Reynolds     for (i=0; i<n; i++) {
2833a873a8cdSSam Reynolds       for (j=0; j<m; j++) {
2834857cbf51SRichard Tran Mills         reductions[i] += PetscRealPart(a[j]);
2835a873a8cdSSam Reynolds       }
2836a873a8cdSSam Reynolds       a += m;
2837a873a8cdSSam Reynolds     }
2838857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2839857cbf51SRichard Tran Mills     for (i=0; i<n; i++) {
2840857cbf51SRichard Tran Mills       for (j=0; j<m; j++) {
2841857cbf51SRichard Tran Mills         reductions[i] += PetscImaginaryPart(a[j]);
2842857cbf51SRichard Tran Mills       }
2843857cbf51SRichard Tran Mills       a += m;
2844857cbf51SRichard Tran Mills     }
2845857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown reduction type");
28461683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&a);CHKERRQ(ierr);
2847857cbf51SRichard Tran Mills   if (type == NORM_2) {
2848a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
2849857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2850a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] /= m;
28510716a85fSBarry Smith   }
28520716a85fSBarry Smith   PetscFunctionReturn(0);
28530716a85fSBarry Smith }
28540716a85fSBarry Smith 
285573a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
285673a71a0fSBarry Smith {
285773a71a0fSBarry Smith   PetscErrorCode ierr;
285873a71a0fSBarry Smith   PetscScalar    *a;
2859637a0070SStefano Zampini   PetscInt       lda,m,n,i,j;
286073a71a0fSBarry Smith 
286173a71a0fSBarry Smith   PetscFunctionBegin;
286273a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
2863637a0070SStefano Zampini   ierr = MatDenseGetLDA(x,&lda);CHKERRQ(ierr);
28648c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
2865637a0070SStefano Zampini   for (j=0; j<n; j++) {
2866637a0070SStefano Zampini     for (i=0; i<m; i++) {
2867637a0070SStefano Zampini       ierr = PetscRandomGetValue(rctx,a+j*lda+i);CHKERRQ(ierr);
2868637a0070SStefano Zampini     }
286973a71a0fSBarry Smith   }
28708c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
287173a71a0fSBarry Smith   PetscFunctionReturn(0);
287273a71a0fSBarry Smith }
287373a71a0fSBarry Smith 
28743b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
28753b49f96aSBarry Smith {
28763b49f96aSBarry Smith   PetscFunctionBegin;
28773b49f96aSBarry Smith   *missing = PETSC_FALSE;
28783b49f96aSBarry Smith   PetscFunctionReturn(0);
28793b49f96aSBarry Smith }
288073a71a0fSBarry Smith 
2881ca15aa20SStefano Zampini /* vals is not const */
2882af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
288386aefd0dSHong Zhang {
2884ca15aa20SStefano Zampini   PetscErrorCode ierr;
288586aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2886ca15aa20SStefano Zampini   PetscScalar    *v;
288786aefd0dSHong Zhang 
288886aefd0dSHong Zhang   PetscFunctionBegin;
288986aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2890ca15aa20SStefano Zampini   ierr  = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2891ca15aa20SStefano Zampini   *vals = v+col*a->lda;
2892ca15aa20SStefano Zampini   ierr  = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
289386aefd0dSHong Zhang   PetscFunctionReturn(0);
289486aefd0dSHong Zhang }
289586aefd0dSHong Zhang 
2896af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
289786aefd0dSHong Zhang {
289886aefd0dSHong Zhang   PetscFunctionBegin;
2899a5b23f4aSJose E. Roman   *vals = NULL; /* user cannot accidentally use the array later */
290086aefd0dSHong Zhang   PetscFunctionReturn(0);
290186aefd0dSHong Zhang }
2902abc3b08eSStefano Zampini 
2903289bc588SBarry Smith /* -------------------------------------------------------------------*/
2904a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2905905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2906905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2907905e6a2fSBarry Smith                                         MatMult_SeqDense,
290897304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
29097c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
29107c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2911f4259b30SLisandro Dalcin                                         NULL,
2912f4259b30SLisandro Dalcin                                         NULL,
2913f4259b30SLisandro Dalcin                                         NULL,
2914f4259b30SLisandro Dalcin                                 /* 10*/ NULL,
2915905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2916905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
291741f059aeSBarry Smith                                         MatSOR_SeqDense,
2918ec8511deSBarry Smith                                         MatTranspose_SeqDense,
291997304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2920905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2921905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2922905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2923905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2924c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2925c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2926905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2927905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2928d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2929f4259b30SLisandro Dalcin                                         NULL,
2930f4259b30SLisandro Dalcin                                         NULL,
2931f4259b30SLisandro Dalcin                                         NULL,
2932f4259b30SLisandro Dalcin                                         NULL,
29334994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2934f4259b30SLisandro Dalcin                                         NULL,
2935f4259b30SLisandro Dalcin                                         NULL,
2936f4259b30SLisandro Dalcin                                         NULL,
2937f4259b30SLisandro Dalcin                                         NULL,
2938d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2939f4259b30SLisandro Dalcin                                         NULL,
2940f4259b30SLisandro Dalcin                                         NULL,
2941f4259b30SLisandro Dalcin                                         NULL,
2942f4259b30SLisandro Dalcin                                         NULL,
2943d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
29447dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2945f4259b30SLisandro Dalcin                                         NULL,
29464b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2947a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2948d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2949a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
29507d68702bSBarry Smith                                         MatShift_Basic,
2951f4259b30SLisandro Dalcin                                         NULL,
29523f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
295373a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2954f4259b30SLisandro Dalcin                                         NULL,
2955f4259b30SLisandro Dalcin                                         NULL,
2956f4259b30SLisandro Dalcin                                         NULL,
2957f4259b30SLisandro Dalcin                                         NULL,
2958f4259b30SLisandro Dalcin                                 /* 54*/ NULL,
2959f4259b30SLisandro Dalcin                                         NULL,
2960f4259b30SLisandro Dalcin                                         NULL,
2961f4259b30SLisandro Dalcin                                         NULL,
2962f4259b30SLisandro Dalcin                                         NULL,
2963023c16fcSToby Isaac                                 /* 59*/ MatCreateSubMatrix_SeqDense,
2964e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2965e03a110bSBarry Smith                                         MatView_SeqDense,
2966f4259b30SLisandro Dalcin                                         NULL,
2967f4259b30SLisandro Dalcin                                         NULL,
2968f4259b30SLisandro Dalcin                                 /* 64*/ NULL,
2969f4259b30SLisandro Dalcin                                         NULL,
2970f4259b30SLisandro Dalcin                                         NULL,
2971f4259b30SLisandro Dalcin                                         NULL,
2972f4259b30SLisandro Dalcin                                         NULL,
2973d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
2974f4259b30SLisandro Dalcin                                         NULL,
2975f4259b30SLisandro Dalcin                                         NULL,
2976f4259b30SLisandro Dalcin                                         NULL,
2977f4259b30SLisandro Dalcin                                         NULL,
2978f4259b30SLisandro Dalcin                                 /* 74*/ NULL,
2979f4259b30SLisandro Dalcin                                         NULL,
2980f4259b30SLisandro Dalcin                                         NULL,
2981f4259b30SLisandro Dalcin                                         NULL,
2982f4259b30SLisandro Dalcin                                         NULL,
2983f4259b30SLisandro Dalcin                                 /* 79*/ NULL,
2984f4259b30SLisandro Dalcin                                         NULL,
2985f4259b30SLisandro Dalcin                                         NULL,
2986f4259b30SLisandro Dalcin                                         NULL,
29875bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2988637a0070SStefano Zampini                                         MatIsSymmetric_SeqDense,
29891cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2990f4259b30SLisandro Dalcin                                         NULL,
2991f4259b30SLisandro Dalcin                                         NULL,
2992f4259b30SLisandro Dalcin                                         NULL,
2993f4259b30SLisandro Dalcin                                 /* 89*/ NULL,
2994f4259b30SLisandro Dalcin                                         NULL,
2995a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2996f4259b30SLisandro Dalcin                                         NULL,
2997f4259b30SLisandro Dalcin                                         NULL,
2998f4259b30SLisandro Dalcin                                 /* 94*/ NULL,
2999f4259b30SLisandro Dalcin                                         NULL,
3000f4259b30SLisandro Dalcin                                         NULL,
300169f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
3002f4259b30SLisandro Dalcin                                         NULL,
30034222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
3004f4259b30SLisandro Dalcin                                         NULL,
3005f4259b30SLisandro Dalcin                                         NULL,
3006ba337c44SJed Brown                                         MatConjugate_SeqDense,
3007f4259b30SLisandro Dalcin                                         NULL,
3008f4259b30SLisandro Dalcin                                 /*104*/ NULL,
3009ba337c44SJed Brown                                         MatRealPart_SeqDense,
3010ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
3011f4259b30SLisandro Dalcin                                         NULL,
3012f4259b30SLisandro Dalcin                                         NULL,
3013f4259b30SLisandro Dalcin                                 /*109*/ NULL,
3014f4259b30SLisandro Dalcin                                         NULL,
30158d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
3016aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
30173b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
3018f4259b30SLisandro Dalcin                                 /*114*/ NULL,
3019f4259b30SLisandro Dalcin                                         NULL,
3020f4259b30SLisandro Dalcin                                         NULL,
3021f4259b30SLisandro Dalcin                                         NULL,
3022f4259b30SLisandro Dalcin                                         NULL,
3023f4259b30SLisandro Dalcin                                 /*119*/ NULL,
3024f4259b30SLisandro Dalcin                                         NULL,
3025f4259b30SLisandro Dalcin                                         NULL,
3026f4259b30SLisandro Dalcin                                         NULL,
3027f4259b30SLisandro Dalcin                                         NULL,
3028f4259b30SLisandro Dalcin                                 /*124*/ NULL,
3029a873a8cdSSam Reynolds                                         MatGetColumnReductions_SeqDense,
3030f4259b30SLisandro Dalcin                                         NULL,
3031f4259b30SLisandro Dalcin                                         NULL,
3032f4259b30SLisandro Dalcin                                         NULL,
3033f4259b30SLisandro Dalcin                                 /*129*/ NULL,
3034f4259b30SLisandro Dalcin                                         NULL,
3035f4259b30SLisandro Dalcin                                         NULL,
303675648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
3037f4259b30SLisandro Dalcin                                         NULL,
3038f4259b30SLisandro Dalcin                                 /*134*/ NULL,
3039f4259b30SLisandro Dalcin                                         NULL,
3040f4259b30SLisandro Dalcin                                         NULL,
3041f4259b30SLisandro Dalcin                                         NULL,
3042f4259b30SLisandro Dalcin                                         NULL,
3043f4259b30SLisandro Dalcin                                 /*139*/ NULL,
3044f4259b30SLisandro Dalcin                                         NULL,
3045f4259b30SLisandro Dalcin                                         NULL,
3046f4259b30SLisandro Dalcin                                         NULL,
3047f4259b30SLisandro Dalcin                                         NULL,
30484222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
3049f4259b30SLisandro Dalcin                                 /*145*/ NULL,
3050f4259b30SLisandro Dalcin                                         NULL,
3051f4259b30SLisandro Dalcin                                         NULL
3052985db425SBarry Smith };
305390ace30eSBarry Smith 
30544b828684SBarry Smith /*@C
3055fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
3056d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
3057d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
3058289bc588SBarry Smith 
3059d083f849SBarry Smith    Collective
3060db81eaa0SLois Curfman McInnes 
306120563c6bSBarry Smith    Input Parameters:
3062db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
30630c775827SLois Curfman McInnes .  m - number of rows
306418f449edSLois Curfman McInnes .  n - number of columns
30650298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
3066dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
306720563c6bSBarry Smith 
306820563c6bSBarry Smith    Output Parameter:
306944cd7ae7SLois Curfman McInnes .  A - the matrix
307020563c6bSBarry Smith 
3071b259b22eSLois Curfman McInnes    Notes:
307218f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
307318f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
30740298fd71SBarry Smith    set data=NULL.
307518f449edSLois Curfman McInnes 
3076027ccd11SLois Curfman McInnes    Level: intermediate
3077027ccd11SLois Curfman McInnes 
307869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
307920563c6bSBarry Smith @*/
30807087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
3081289bc588SBarry Smith {
3082dfbe8321SBarry Smith   PetscErrorCode ierr;
30833b2fbd54SBarry Smith 
30843a40ed3dSBarry Smith   PetscFunctionBegin;
3085f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3086f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3087273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
3088273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
3089273d9f13SBarry Smith   PetscFunctionReturn(0);
3090273d9f13SBarry Smith }
3091273d9f13SBarry Smith 
3092273d9f13SBarry Smith /*@C
3093273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
3094273d9f13SBarry Smith 
3095d083f849SBarry Smith    Collective
3096273d9f13SBarry Smith 
3097273d9f13SBarry Smith    Input Parameters:
30981c4f3114SJed Brown +  B - the matrix
30990298fd71SBarry Smith -  data - the array (or NULL)
3100273d9f13SBarry Smith 
3101273d9f13SBarry Smith    Notes:
3102273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
3103273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
3104284134d9SBarry Smith    need not call this routine.
3105273d9f13SBarry Smith 
3106273d9f13SBarry Smith    Level: intermediate
3107273d9f13SBarry Smith 
3108ad16ce7aSStefano Zampini .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatDenseSetLDA()
3109867c911aSBarry Smith 
3110273d9f13SBarry Smith @*/
31117087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
3112273d9f13SBarry Smith {
31134ac538c5SBarry Smith   PetscErrorCode ierr;
3114a23d5eceSKris Buschelman 
3115a23d5eceSKris Buschelman   PetscFunctionBegin;
3116d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
31174ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
3118a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3119a23d5eceSKris Buschelman }
3120a23d5eceSKris Buschelman 
31217087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
3122a23d5eceSKris Buschelman {
3123ad16ce7aSStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
3124dfbe8321SBarry Smith   PetscErrorCode ierr;
3125273d9f13SBarry Smith 
3126273d9f13SBarry Smith   PetscFunctionBegin;
3127616b8fbbSStefano Zampini   if (b->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
3128273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3129a868139aSShri Abhyankar 
313034ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
313134ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
313234ef9618SShri Abhyankar 
3133ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
313486d161a7SShri Abhyankar 
3135ad16ce7aSStefano Zampini   ierr = PetscIntMultError(b->lda,B->cmap->n,NULL);CHKERRQ(ierr);
31369e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
31379e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
3138ad16ce7aSStefano Zampini     ierr = PetscCalloc1((size_t)b->lda*B->cmap->n,&b->v);CHKERRQ(ierr);
3139ad16ce7aSStefano Zampini     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*B->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
31402205254eSKarl Rupp 
31419e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
3142273d9f13SBarry Smith   } else { /* user-allocated storage */
31439e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
3144273d9f13SBarry Smith     b->v          = data;
3145273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
3146273d9f13SBarry Smith   }
31470450473dSBarry Smith   B->assembled = PETSC_TRUE;
3148273d9f13SBarry Smith   PetscFunctionReturn(0);
3149273d9f13SBarry Smith }
3150273d9f13SBarry Smith 
315165b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3152cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
31538baccfbdSHong Zhang {
3154d77f618aSHong Zhang   Mat               mat_elemental;
3155d77f618aSHong Zhang   PetscErrorCode    ierr;
31561683a169SBarry Smith   const PetscScalar *array;
31571683a169SBarry Smith   PetscScalar       *v_colwise;
3158d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
3159d77f618aSHong Zhang 
31608baccfbdSHong Zhang   PetscFunctionBegin;
3161d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
31621683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&array);CHKERRQ(ierr);
3163d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3164d77f618aSHong Zhang   k = 0;
3165d77f618aSHong Zhang   for (j=0; j<N; j++) {
3166d77f618aSHong Zhang     cols[j] = j;
3167d77f618aSHong Zhang     for (i=0; i<M; i++) {
3168d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
3169d77f618aSHong Zhang     }
3170d77f618aSHong Zhang   }
3171d77f618aSHong Zhang   for (i=0; i<M; i++) {
3172d77f618aSHong Zhang     rows[i] = i;
3173d77f618aSHong Zhang   }
31741683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&array);CHKERRQ(ierr);
3175d77f618aSHong Zhang 
3176d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
3177d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
3178d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
3179d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
3180d77f618aSHong Zhang 
3181d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
3182d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
3183d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3184d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3185d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
3186d77f618aSHong Zhang 
3187511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
318828be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
3189d77f618aSHong Zhang   } else {
3190d77f618aSHong Zhang     *newmat = mat_elemental;
3191d77f618aSHong Zhang   }
31928baccfbdSHong Zhang   PetscFunctionReturn(0);
31938baccfbdSHong Zhang }
319465b80a83SHong Zhang #endif
31958baccfbdSHong Zhang 
319617359960SJose E. Roman PetscErrorCode  MatDenseSetLDA_SeqDense(Mat B,PetscInt lda)
31971b807ce4Svictorle {
31981b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
31997422da62SJose E. Roman   PetscBool    data;
320021a2c019SBarry Smith 
32011b807ce4Svictorle   PetscFunctionBegin;
32027422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
32037422da62SJose 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");
3204e32f2f54SBarry 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);
32051b807ce4Svictorle   b->lda = lda;
32061b807ce4Svictorle   PetscFunctionReturn(0);
32071b807ce4Svictorle }
32081b807ce4Svictorle 
3209d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
3210d528f656SJakub Kruzik {
3211d528f656SJakub Kruzik   PetscErrorCode ierr;
3212d528f656SJakub Kruzik   PetscMPIInt    size;
3213d528f656SJakub Kruzik 
3214d528f656SJakub Kruzik   PetscFunctionBegin;
3215ffc4695bSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr);
3216d528f656SJakub Kruzik   if (size == 1) {
3217d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
3218d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
3219d528f656SJakub Kruzik     } else {
3220d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
3221d528f656SJakub Kruzik     }
3222d528f656SJakub Kruzik   } else {
3223d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
3224d528f656SJakub Kruzik   }
3225d528f656SJakub Kruzik   PetscFunctionReturn(0);
3226d528f656SJakub Kruzik }
3227d528f656SJakub Kruzik 
32286947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
32296947451fSStefano Zampini {
32306947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32316947451fSStefano Zampini   PetscErrorCode ierr;
32326947451fSStefano Zampini 
32336947451fSStefano Zampini   PetscFunctionBegin;
32345ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
32355ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32366947451fSStefano Zampini   if (!a->cvec) {
32376947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
3238616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
32396947451fSStefano Zampini   }
32406947451fSStefano Zampini   a->vecinuse = col + 1;
32416947451fSStefano Zampini   ierr = MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
32426947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
32436947451fSStefano Zampini   *v   = a->cvec;
32446947451fSStefano Zampini   PetscFunctionReturn(0);
32456947451fSStefano Zampini }
32466947451fSStefano Zampini 
32476947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
32486947451fSStefano Zampini {
32496947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32506947451fSStefano Zampini   PetscErrorCode ierr;
32516947451fSStefano Zampini 
32526947451fSStefano Zampini   PetscFunctionBegin;
32535ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
32546947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
32556947451fSStefano Zampini   a->vecinuse = 0;
32566947451fSStefano Zampini   ierr = MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
32576947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
32586947451fSStefano Zampini   *v   = NULL;
32596947451fSStefano Zampini   PetscFunctionReturn(0);
32606947451fSStefano Zampini }
32616947451fSStefano Zampini 
32626947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
32636947451fSStefano Zampini {
32646947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32656947451fSStefano Zampini   PetscErrorCode ierr;
32666947451fSStefano Zampini 
32676947451fSStefano Zampini   PetscFunctionBegin;
32685ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
32695ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32706947451fSStefano Zampini   if (!a->cvec) {
32716947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
3272616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
32736947451fSStefano Zampini   }
32746947451fSStefano Zampini   a->vecinuse = col + 1;
32756947451fSStefano Zampini   ierr = MatDenseGetArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
32766947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
32776947451fSStefano Zampini   ierr = VecLockReadPush(a->cvec);CHKERRQ(ierr);
32786947451fSStefano Zampini   *v   = a->cvec;
32796947451fSStefano Zampini   PetscFunctionReturn(0);
32806947451fSStefano Zampini }
32816947451fSStefano Zampini 
32826947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
32836947451fSStefano Zampini {
32846947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32856947451fSStefano Zampini   PetscErrorCode ierr;
32866947451fSStefano Zampini 
32876947451fSStefano Zampini   PetscFunctionBegin;
32885ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
32896947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
32906947451fSStefano Zampini   a->vecinuse = 0;
32916947451fSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
32926947451fSStefano Zampini   ierr = VecLockReadPop(a->cvec);CHKERRQ(ierr);
32936947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
32946947451fSStefano Zampini   *v   = NULL;
32956947451fSStefano Zampini   PetscFunctionReturn(0);
32966947451fSStefano Zampini }
32976947451fSStefano Zampini 
32986947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
32996947451fSStefano Zampini {
33006947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
33016947451fSStefano Zampini   PetscErrorCode ierr;
33026947451fSStefano Zampini 
33036947451fSStefano Zampini   PetscFunctionBegin;
33045ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
33055ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
33066947451fSStefano Zampini   if (!a->cvec) {
33076947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
3308616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
33096947451fSStefano Zampini   }
33106947451fSStefano Zampini   a->vecinuse = col + 1;
33116947451fSStefano Zampini   ierr = MatDenseGetArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
33126947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
33136947451fSStefano Zampini   *v   = a->cvec;
33146947451fSStefano Zampini   PetscFunctionReturn(0);
33156947451fSStefano Zampini }
33166947451fSStefano Zampini 
33176947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
33186947451fSStefano Zampini {
33196947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
33206947451fSStefano Zampini   PetscErrorCode ierr;
33216947451fSStefano Zampini 
33226947451fSStefano Zampini   PetscFunctionBegin;
33235ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
33246947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
33256947451fSStefano Zampini   a->vecinuse = 0;
33266947451fSStefano Zampini   ierr = MatDenseRestoreArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
33276947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
33286947451fSStefano Zampini   *v   = NULL;
33296947451fSStefano Zampini   PetscFunctionReturn(0);
33306947451fSStefano Zampini }
33316947451fSStefano Zampini 
33325ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
33335ea7661aSPierre Jolivet {
33345ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
33355ea7661aSPierre Jolivet   PetscErrorCode ierr;
33365ea7661aSPierre Jolivet 
33375ea7661aSPierre Jolivet   PetscFunctionBegin;
33385ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
33395ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
33405ea7661aSPierre Jolivet   if (a->cmat && cend-cbegin != a->cmat->cmap->N) {
33415ea7661aSPierre Jolivet     ierr = MatDestroy(&a->cmat);CHKERRQ(ierr);
33425ea7661aSPierre Jolivet   }
33435ea7661aSPierre Jolivet   if (!a->cmat) {
3344616b8fbbSStefano 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);
3345616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cmat);CHKERRQ(ierr);
33465ea7661aSPierre Jolivet   } else {
3347616b8fbbSStefano Zampini     ierr = MatDensePlaceArray(a->cmat,a->v + (size_t)cbegin * (size_t)a->lda);CHKERRQ(ierr);
33485ea7661aSPierre Jolivet   }
3349616b8fbbSStefano Zampini   ierr = MatDenseSetLDA(a->cmat,a->lda);CHKERRQ(ierr);
33505ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
33515ea7661aSPierre Jolivet   *v = a->cmat;
33525ea7661aSPierre Jolivet   PetscFunctionReturn(0);
33535ea7661aSPierre Jolivet }
33545ea7661aSPierre Jolivet 
33555ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A,Mat *v)
33565ea7661aSPierre Jolivet {
33575ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
33585ea7661aSPierre Jolivet   PetscErrorCode ierr;
33595ea7661aSPierre Jolivet 
33605ea7661aSPierre Jolivet   PetscFunctionBegin;
33615ea7661aSPierre Jolivet   if (!a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetSubMatrix() first");
33625ea7661aSPierre Jolivet   if (!a->cmat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column matrix");
3363616b8fbbSStefano Zampini   if (*v != a->cmat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not the matrix obtained from MatDenseGetSubMatrix()");
33645ea7661aSPierre Jolivet   a->matinuse = 0;
33655ea7661aSPierre Jolivet   ierr = MatDenseResetArray(a->cmat);CHKERRQ(ierr);
33665ea7661aSPierre Jolivet   *v   = NULL;
33675ea7661aSPierre Jolivet   PetscFunctionReturn(0);
33685ea7661aSPierre Jolivet }
33695ea7661aSPierre Jolivet 
33700bad9183SKris Buschelman /*MC
3371fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
33720bad9183SKris Buschelman 
33730bad9183SKris Buschelman    Options Database Keys:
33740bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
33750bad9183SKris Buschelman 
33760bad9183SKris Buschelman   Level: beginner
33770bad9183SKris Buschelman 
337889665df3SBarry Smith .seealso: MatCreateSeqDense()
337989665df3SBarry Smith 
33800bad9183SKris Buschelman M*/
3381ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
3382273d9f13SBarry Smith {
3383273d9f13SBarry Smith   Mat_SeqDense   *b;
3384dfbe8321SBarry Smith   PetscErrorCode ierr;
33857c334f02SBarry Smith   PetscMPIInt    size;
3386273d9f13SBarry Smith 
3387273d9f13SBarry Smith   PetscFunctionBegin;
3388ffc4695bSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRMPI(ierr);
3389e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
339055659b69SBarry Smith 
3391b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
3392549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
339344cd7ae7SLois Curfman McInnes   B->data = (void*)b;
339418f449edSLois Curfman McInnes 
3395273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
33964e220ebcSLois Curfman McInnes 
33974905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)B,"MatQRFactor_C",MatQRFactor_SeqDense);CHKERRQ(ierr);
339849a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
3399ad16ce7aSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseSetLDA_C",MatDenseSetLDA_SeqDense);CHKERRQ(ierr);
3400bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
34018572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
3402d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
3403d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
3404d5ea218eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseReplaceArray_C",MatDenseReplaceArray_SeqDense);CHKERRQ(ierr);
34058572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
3406715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
34076947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayWrite_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
34086947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayWrite_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
3409bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
34108baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
34118baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
34128baccfbdSHong Zhang #endif
3413d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
3414d24d4204SJose E. Roman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_scalapack_C",MatConvert_Dense_ScaLAPACK);CHKERRQ(ierr);
3415d24d4204SJose E. Roman #endif
34162bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
34172bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA);CHKERRQ(ierr);
34184222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
34194222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
3420637a0070SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
34212bf066beSStefano Zampini #endif
3422bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
34234222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
34244222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
34254222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
34264222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
342796e6d5c4SRichard Tran Mills 
3428af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
3429af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
34306947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVec_C",MatDenseGetColumnVec_SeqDense);CHKERRQ(ierr);
34316947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVec_C",MatDenseRestoreColumnVec_SeqDense);CHKERRQ(ierr);
34326947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecRead_C",MatDenseGetColumnVecRead_SeqDense);CHKERRQ(ierr);
34336947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecRead_C",MatDenseRestoreColumnVecRead_SeqDense);CHKERRQ(ierr);
34346947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecWrite_C",MatDenseGetColumnVecWrite_SeqDense);CHKERRQ(ierr);
34356947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecWrite_C",MatDenseRestoreColumnVecWrite_SeqDense);CHKERRQ(ierr);
34365ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetSubMatrix_C",MatDenseGetSubMatrix_SeqDense);CHKERRQ(ierr);
34375ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreSubMatrix_C",MatDenseRestoreSubMatrix_SeqDense);CHKERRQ(ierr);
343817667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
34393a40ed3dSBarry Smith   PetscFunctionReturn(0);
3440289bc588SBarry Smith }
344186aefd0dSHong Zhang 
344286aefd0dSHong Zhang /*@C
3443af53bab2SHong 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.
344486aefd0dSHong Zhang 
344586aefd0dSHong Zhang    Not Collective
344686aefd0dSHong Zhang 
34475ea7661aSPierre Jolivet    Input Parameters:
344886aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
344986aefd0dSHong Zhang -  col - column index
345086aefd0dSHong Zhang 
345186aefd0dSHong Zhang    Output Parameter:
345286aefd0dSHong Zhang .  vals - pointer to the data
345386aefd0dSHong Zhang 
345486aefd0dSHong Zhang    Level: intermediate
345586aefd0dSHong Zhang 
345686aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
345786aefd0dSHong Zhang @*/
345886aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
345986aefd0dSHong Zhang {
346086aefd0dSHong Zhang   PetscErrorCode ierr;
346186aefd0dSHong Zhang 
346286aefd0dSHong Zhang   PetscFunctionBegin;
3463d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3464d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3465d5ea218eSStefano Zampini   PetscValidPointer(vals,3);
346686aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
346786aefd0dSHong Zhang   PetscFunctionReturn(0);
346886aefd0dSHong Zhang }
346986aefd0dSHong Zhang 
347086aefd0dSHong Zhang /*@C
347186aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
347286aefd0dSHong Zhang 
347386aefd0dSHong Zhang    Not Collective
347486aefd0dSHong Zhang 
347586aefd0dSHong Zhang    Input Parameter:
347686aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
347786aefd0dSHong Zhang 
347886aefd0dSHong Zhang    Output Parameter:
347986aefd0dSHong Zhang .  vals - pointer to the data
348086aefd0dSHong Zhang 
348186aefd0dSHong Zhang    Level: intermediate
348286aefd0dSHong Zhang 
348386aefd0dSHong Zhang .seealso: MatDenseGetColumn()
348486aefd0dSHong Zhang @*/
348586aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
348686aefd0dSHong Zhang {
348786aefd0dSHong Zhang   PetscErrorCode ierr;
348886aefd0dSHong Zhang 
348986aefd0dSHong Zhang   PetscFunctionBegin;
3490d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3491d5ea218eSStefano Zampini   PetscValidPointer(vals,2);
349286aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
349386aefd0dSHong Zhang   PetscFunctionReturn(0);
349486aefd0dSHong Zhang }
34956947451fSStefano Zampini 
34966947451fSStefano Zampini /*@C
34976947451fSStefano Zampini    MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec.
34986947451fSStefano Zampini 
34996947451fSStefano Zampini    Collective
35006947451fSStefano Zampini 
35015ea7661aSPierre Jolivet    Input Parameters:
35026947451fSStefano Zampini +  mat - the Mat object
35036947451fSStefano Zampini -  col - the column index
35046947451fSStefano Zampini 
35056947451fSStefano Zampini    Output Parameter:
35066947451fSStefano Zampini .  v - the vector
35076947451fSStefano Zampini 
35086947451fSStefano Zampini    Notes:
35096947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed.
35106947451fSStefano Zampini      Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access.
35116947451fSStefano Zampini 
35126947451fSStefano Zampini    Level: intermediate
35136947451fSStefano Zampini 
35146947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
35156947451fSStefano Zampini @*/
35166947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec(Mat A,PetscInt col,Vec *v)
35176947451fSStefano Zampini {
35186947451fSStefano Zampini   PetscErrorCode ierr;
35196947451fSStefano Zampini 
35206947451fSStefano Zampini   PetscFunctionBegin;
35216947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35226947451fSStefano Zampini   PetscValidType(A,1);
35236947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35246947451fSStefano Zampini   PetscValidPointer(v,3);
35256947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35266947451fSStefano 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);
35276947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
35286947451fSStefano Zampini   PetscFunctionReturn(0);
35296947451fSStefano Zampini }
35306947451fSStefano Zampini 
35316947451fSStefano Zampini /*@C
35326947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
35336947451fSStefano Zampini 
35346947451fSStefano Zampini    Collective
35356947451fSStefano Zampini 
35365ea7661aSPierre Jolivet    Input Parameters:
35376947451fSStefano Zampini +  mat - the Mat object
35386947451fSStefano Zampini .  col - the column index
35396947451fSStefano Zampini -  v - the Vec object
35406947451fSStefano Zampini 
35416947451fSStefano Zampini    Level: intermediate
35426947451fSStefano Zampini 
35436947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
35446947451fSStefano Zampini @*/
35456947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec *v)
35466947451fSStefano Zampini {
35476947451fSStefano Zampini   PetscErrorCode ierr;
35486947451fSStefano Zampini 
35496947451fSStefano Zampini   PetscFunctionBegin;
35506947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35516947451fSStefano Zampini   PetscValidType(A,1);
35526947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35536947451fSStefano Zampini   PetscValidPointer(v,3);
35546947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35556947451fSStefano 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);
35566947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
35576947451fSStefano Zampini   PetscFunctionReturn(0);
35586947451fSStefano Zampini }
35596947451fSStefano Zampini 
35606947451fSStefano Zampini /*@C
35616947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
35626947451fSStefano Zampini 
35636947451fSStefano Zampini    Collective
35646947451fSStefano Zampini 
35655ea7661aSPierre Jolivet    Input Parameters:
35666947451fSStefano Zampini +  mat - the Mat object
35676947451fSStefano Zampini -  col - the column index
35686947451fSStefano Zampini 
35696947451fSStefano Zampini    Output Parameter:
35706947451fSStefano Zampini .  v - the vector
35716947451fSStefano Zampini 
35726947451fSStefano Zampini    Notes:
35736947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
35746947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
35756947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
35766947451fSStefano Zampini 
35776947451fSStefano Zampini    Level: intermediate
35786947451fSStefano Zampini 
35796947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
35806947451fSStefano Zampini @*/
35816947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec *v)
35826947451fSStefano Zampini {
35836947451fSStefano Zampini   PetscErrorCode ierr;
35846947451fSStefano Zampini 
35856947451fSStefano Zampini   PetscFunctionBegin;
35866947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35876947451fSStefano Zampini   PetscValidType(A,1);
35886947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35896947451fSStefano Zampini   PetscValidPointer(v,3);
35906947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35916947451fSStefano 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);
35926947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
35936947451fSStefano Zampini   PetscFunctionReturn(0);
35946947451fSStefano Zampini }
35956947451fSStefano Zampini 
35966947451fSStefano Zampini /*@C
35976947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
35986947451fSStefano Zampini 
35996947451fSStefano Zampini    Collective
36006947451fSStefano Zampini 
36015ea7661aSPierre Jolivet    Input Parameters:
36026947451fSStefano Zampini +  mat - the Mat object
36036947451fSStefano Zampini .  col - the column index
36046947451fSStefano Zampini -  v - the Vec object
36056947451fSStefano Zampini 
36066947451fSStefano Zampini    Level: intermediate
36076947451fSStefano Zampini 
36086947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecWrite()
36096947451fSStefano Zampini @*/
36106947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec *v)
36116947451fSStefano Zampini {
36126947451fSStefano Zampini   PetscErrorCode ierr;
36136947451fSStefano Zampini 
36146947451fSStefano Zampini   PetscFunctionBegin;
36156947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36166947451fSStefano Zampini   PetscValidType(A,1);
36176947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
36186947451fSStefano Zampini   PetscValidPointer(v,3);
36196947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
36206947451fSStefano 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);
36216947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
36226947451fSStefano Zampini   PetscFunctionReturn(0);
36236947451fSStefano Zampini }
36246947451fSStefano Zampini 
36256947451fSStefano Zampini /*@C
36266947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
36276947451fSStefano Zampini 
36286947451fSStefano Zampini    Collective
36296947451fSStefano Zampini 
36305ea7661aSPierre Jolivet    Input Parameters:
36316947451fSStefano Zampini +  mat - the Mat object
36326947451fSStefano Zampini -  col - the column index
36336947451fSStefano Zampini 
36346947451fSStefano Zampini    Output Parameter:
36356947451fSStefano Zampini .  v - the vector
36366947451fSStefano Zampini 
36376947451fSStefano Zampini    Notes:
36386947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
36396947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
36406947451fSStefano Zampini 
36416947451fSStefano Zampini    Level: intermediate
36426947451fSStefano Zampini 
36436947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
36446947451fSStefano Zampini @*/
36456947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec *v)
36466947451fSStefano Zampini {
36476947451fSStefano Zampini   PetscErrorCode ierr;
36486947451fSStefano Zampini 
36496947451fSStefano Zampini   PetscFunctionBegin;
36506947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36516947451fSStefano Zampini   PetscValidType(A,1);
36526947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
36536947451fSStefano Zampini   PetscValidPointer(v,3);
36546947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
36556947451fSStefano 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);
36566947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
36576947451fSStefano Zampini   PetscFunctionReturn(0);
36586947451fSStefano Zampini }
36596947451fSStefano Zampini 
36606947451fSStefano Zampini /*@C
36616947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
36626947451fSStefano Zampini 
36636947451fSStefano Zampini    Collective
36646947451fSStefano Zampini 
36655ea7661aSPierre Jolivet    Input Parameters:
36666947451fSStefano Zampini +  mat - the Mat object
36676947451fSStefano Zampini .  col - the column index
36686947451fSStefano Zampini -  v - the Vec object
36696947451fSStefano Zampini 
36706947451fSStefano Zampini    Level: intermediate
36716947451fSStefano Zampini 
36726947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead()
36736947451fSStefano Zampini @*/
36746947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec *v)
36756947451fSStefano Zampini {
36766947451fSStefano Zampini   PetscErrorCode ierr;
36776947451fSStefano Zampini 
36786947451fSStefano Zampini   PetscFunctionBegin;
36796947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36806947451fSStefano Zampini   PetscValidType(A,1);
36816947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
36826947451fSStefano Zampini   PetscValidPointer(v,3);
36836947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
36846947451fSStefano 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);
36856947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
36866947451fSStefano Zampini   PetscFunctionReturn(0);
36876947451fSStefano Zampini }
36885ea7661aSPierre Jolivet 
36895ea7661aSPierre Jolivet /*@C
36905ea7661aSPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of columns of a dense matrix, represented as a Mat.
36915ea7661aSPierre Jolivet 
36925ea7661aSPierre Jolivet    Collective
36935ea7661aSPierre Jolivet 
36945ea7661aSPierre Jolivet    Input Parameters:
36955ea7661aSPierre Jolivet +  mat - the Mat object
36965ea7661aSPierre Jolivet .  cbegin - the first index in the block
36975ea7661aSPierre Jolivet -  cend - the last index in the block
36985ea7661aSPierre Jolivet 
36995ea7661aSPierre Jolivet    Output Parameter:
37005ea7661aSPierre Jolivet .  v - the matrix
37015ea7661aSPierre Jolivet 
37025ea7661aSPierre Jolivet    Notes:
37035ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
37045ea7661aSPierre Jolivet 
37055ea7661aSPierre Jolivet    Level: intermediate
37065ea7661aSPierre Jolivet 
37075ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseRestoreSubMatrix()
37085ea7661aSPierre Jolivet @*/
37095ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
37105ea7661aSPierre Jolivet {
37115ea7661aSPierre Jolivet   PetscErrorCode ierr;
37125ea7661aSPierre Jolivet 
37135ea7661aSPierre Jolivet   PetscFunctionBegin;
37145ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
37155ea7661aSPierre Jolivet   PetscValidType(A,1);
37165ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cbegin,2);
37175ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cend,3);
37185ea7661aSPierre Jolivet   PetscValidPointer(v,4);
37195ea7661aSPierre Jolivet   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
37205ea7661aSPierre 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);
3721616b8fbbSStefano 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);
37225ea7661aSPierre Jolivet   ierr = PetscUseMethod(A,"MatDenseGetSubMatrix_C",(Mat,PetscInt,PetscInt,Mat*),(A,cbegin,cend,v));CHKERRQ(ierr);
37235ea7661aSPierre Jolivet   PetscFunctionReturn(0);
37245ea7661aSPierre Jolivet }
37255ea7661aSPierre Jolivet 
37265ea7661aSPierre Jolivet /*@C
37275ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
37285ea7661aSPierre Jolivet 
37295ea7661aSPierre Jolivet    Collective
37305ea7661aSPierre Jolivet 
37315ea7661aSPierre Jolivet    Input Parameters:
37325ea7661aSPierre Jolivet +  mat - the Mat object
37335ea7661aSPierre Jolivet -  v - the Mat object
37345ea7661aSPierre Jolivet 
37355ea7661aSPierre Jolivet    Level: intermediate
37365ea7661aSPierre Jolivet 
37375ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseGetSubMatrix()
37385ea7661aSPierre Jolivet @*/
37395ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix(Mat A,Mat *v)
37405ea7661aSPierre Jolivet {
37415ea7661aSPierre Jolivet   PetscErrorCode ierr;
37425ea7661aSPierre Jolivet 
37435ea7661aSPierre Jolivet   PetscFunctionBegin;
37445ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
37455ea7661aSPierre Jolivet   PetscValidType(A,1);
37465ea7661aSPierre Jolivet   PetscValidPointer(v,2);
37475ea7661aSPierre Jolivet   ierr = PetscUseMethod(A,"MatDenseRestoreSubMatrix_C",(Mat,Mat*),(A,v));CHKERRQ(ierr);
37485ea7661aSPierre Jolivet   PetscFunctionReturn(0);
37495ea7661aSPierre Jolivet }
3750