xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 75f6d85da25b72b45a8b9e65290bf04ed632e948)
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;
192c71b3e2SJacob Faibussowitsch   PetscCheckFalse(A->rmap->n != A->cmap->n,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) {
482c71b3e2SJacob Faibussowitsch     PetscCheckFalse(!mat->pivots,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) {
662c71b3e2SJacob Faibussowitsch       PetscCheckFalse(!mat->pivots,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
672c71b3e2SJacob Faibussowitsch       PetscCheckFalse(!mat->fwork,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 */
742c71b3e2SJacob Faibussowitsch       PetscCheckFalse(!mat->pivots,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
752c71b3e2SJacob Faibussowitsch       PetscCheckFalse(!mat->fwork,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     }
812c71b3e2SJacob Faibussowitsch     PetscCheckFalse(info,PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad Inversion: zero pivot in row %" PetscInt_FMT,(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++) {
1072c71b3e2SJacob Faibussowitsch       PetscCheckFalse(rows[i] < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1082c71b3e2SJacob Faibussowitsch       PetscCheckFalse(rows[i] >= A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %" PetscInt_FMT " requested to be zeroed greater than or equal number of rows %" PetscInt_FMT,rows[i],A->rmap->n);
1092c71b3e2SJacob Faibussowitsch       PetscCheckFalse(rows[i] >= A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Col %" PetscInt_FMT " requested to be zeroed greater than or equal number of cols %" PetscInt_FMT,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 
1182c71b3e2SJacob Faibussowitsch     PetscCheckFalse(A->rmap->n != A->cmap->n,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) {
1412c71b3e2SJacob Faibussowitsch     PetscCheckFalse(A->rmap->n != A->cmap->n,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);
2012c71b3e2SJacob Faibussowitsch     PetscCheckFalse(!isseqdense,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;
400*75f6d85dSStefano Zampini   PetscBool      isdensecpu;
401b24902e0SBarry Smith 
402b24902e0SBarry Smith   PetscFunctionBegin;
403aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr);
404aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr);
40523fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
40623fc5dcaSStefano Zampini     ierr = MatDenseSetLDA(newi,lda);CHKERRQ(ierr);
40723fc5dcaSStefano Zampini   }
408*75f6d85dSStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)newi,MATSEQDENSE,&isdensecpu);CHKERRQ(ierr);
409*75f6d85dSStefano Zampini   if (isdensecpu) { ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr); }
410b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
411ca15aa20SStefano Zampini     const PetscScalar *av;
412ca15aa20SStefano Zampini     PetscScalar       *v;
413ca15aa20SStefano Zampini 
414ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
415*75f6d85dSStefano Zampini     ierr = MatDenseGetArrayWrite(newi,&v);CHKERRQ(ierr);
41623fc5dcaSStefano Zampini     ierr = MatDenseGetLDA(newi,&nlda);CHKERRQ(ierr);
417d0f46423SBarry Smith     m    = A->rmap->n;
41823fc5dcaSStefano Zampini     if (lda>m || nlda>m) {
419d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
42023fc5dcaSStefano Zampini         ierr = PetscArraycpy(v+j*nlda,av+j*lda,m);CHKERRQ(ierr);
421b24902e0SBarry Smith       }
422b24902e0SBarry Smith     } else {
423ca15aa20SStefano Zampini       ierr = PetscArraycpy(v,av,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
424b24902e0SBarry Smith     }
425*75f6d85dSStefano Zampini     ierr = MatDenseRestoreArrayWrite(newi,&v);CHKERRQ(ierr);
426ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
427b24902e0SBarry Smith   }
428b24902e0SBarry Smith   PetscFunctionReturn(0);
429b24902e0SBarry Smith }
430b24902e0SBarry Smith 
431ca15aa20SStefano Zampini PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
43202cad45dSBarry Smith {
4336849ba73SBarry Smith   PetscErrorCode ierr;
43402cad45dSBarry Smith 
4353a40ed3dSBarry Smith   PetscFunctionBegin;
436ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr);
437d0f46423SBarry Smith   ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4385c9eb25fSBarry Smith   ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
439719d5645SBarry Smith   ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr);
440b24902e0SBarry Smith   PetscFunctionReturn(0);
441b24902e0SBarry Smith }
442b24902e0SBarry Smith 
443bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
444289bc588SBarry Smith {
445c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4464396437dSToby Isaac   PetscBLASInt    info;
4476849ba73SBarry Smith   PetscErrorCode  ierr;
44867e560aaSBarry Smith 
4493a40ed3dSBarry Smith   PetscFunctionBegin;
45000121966SStefano Zampini   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4514396437dSToby Isaac   PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_(T ? "T" : "N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
45200121966SStefano Zampini   ierr = PetscFPTrapPop();CHKERRQ(ierr);
4532c71b3e2SJacob Faibussowitsch   PetscCheckFalse(info,PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
4544905a7bcSToby Isaac   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
4554396437dSToby Isaac   PetscFunctionReturn(0);
4564396437dSToby Isaac }
4574396437dSToby Isaac 
4584396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat);
4594396437dSToby Isaac 
460bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
4614396437dSToby Isaac {
4624396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4634396437dSToby Isaac   PetscBLASInt    info;
4644396437dSToby Isaac   PetscErrorCode  ierr;
4654396437dSToby Isaac 
4664396437dSToby Isaac   PetscFunctionBegin;
467a49dc2a2SStefano Zampini   if (A->spd) {
4684396437dSToby Isaac     if (PetscDefined(USE_COMPLEX) && T) {ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);}
46900121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4708b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
47100121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
4722c71b3e2SJacob Faibussowitsch     PetscCheckFalse(info,PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
4734396437dSToby Isaac     if (PetscDefined(USE_COMPLEX) && T) {ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);}
474a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
475a49dc2a2SStefano Zampini   } else if (A->hermitian) {
4764396437dSToby Isaac     if (T) {ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);}
47700121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
478a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
47900121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
4802c71b3e2SJacob Faibussowitsch     PetscCheckFalse(info,PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
4814396437dSToby Isaac     if (T) {ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);}
482a49dc2a2SStefano Zampini #endif
483a49dc2a2SStefano Zampini   } else { /* symmetric case */
48400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
485a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
48600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
4872c71b3e2SJacob Faibussowitsch     PetscCheckFalse(info,PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
488a49dc2a2SStefano Zampini   }
4894905a7bcSToby Isaac   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
4904396437dSToby Isaac   PetscFunctionReturn(0);
4914396437dSToby Isaac }
49285e2c93fSHong Zhang 
493bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
4944396437dSToby Isaac {
4954396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4964396437dSToby Isaac   PetscBLASInt    info;
4974396437dSToby Isaac   char            trans;
4984396437dSToby Isaac   PetscErrorCode  ierr;
4994396437dSToby Isaac 
5004396437dSToby Isaac   PetscFunctionBegin;
5014905a7bcSToby Isaac   if (PetscDefined(USE_COMPLEX)) {
5024905a7bcSToby Isaac     trans = 'C';
5034905a7bcSToby Isaac   } else {
5044905a7bcSToby Isaac     trans = 'T';
5054905a7bcSToby Isaac   }
5064905a7bcSToby Isaac   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
507bf5a80bcSToby Isaac   PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", &trans, &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,mat->fwork,&mat->lfwork,&info));
5084905a7bcSToby Isaac   ierr = PetscFPTrapPop();CHKERRQ(ierr);
5092c71b3e2SJacob Faibussowitsch   PetscCheckFalse(info,PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform");
5104905a7bcSToby Isaac   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
511bf5a80bcSToby Isaac   PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "N", "N", &mat->rank,&nrhs,mat->v,&mat->lda,x,&ldx,&info));
5124905a7bcSToby Isaac   ierr = PetscFPTrapPop();CHKERRQ(ierr);
5132c71b3e2SJacob Faibussowitsch   PetscCheckFalse(info,PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve");
5144905a7bcSToby Isaac   for (PetscInt j = 0; j < nrhs; j++) {
5154905a7bcSToby Isaac     for (PetscInt i = mat->rank; i < k; i++) {
516bf5a80bcSToby Isaac       x[j*ldx + i] = 0.;
5174905a7bcSToby Isaac     }
5184905a7bcSToby Isaac   }
5194905a7bcSToby Isaac   ierr = PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank)));CHKERRQ(ierr);
5204905a7bcSToby Isaac   PetscFunctionReturn(0);
5214905a7bcSToby Isaac }
5224905a7bcSToby Isaac 
523bf5a80bcSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
5244905a7bcSToby Isaac {
5254396437dSToby Isaac   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
5264396437dSToby Isaac   PetscBLASInt      info;
5274905a7bcSToby Isaac   PetscErrorCode    ierr;
5284396437dSToby Isaac 
5294396437dSToby Isaac   PetscFunctionBegin;
5304396437dSToby Isaac   if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
5314396437dSToby Isaac     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
532bf5a80bcSToby Isaac     PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "T", "N", &m,&nrhs,mat->v,&mat->lda,x,&ldx,&info));
5334396437dSToby Isaac     ierr = PetscFPTrapPop();CHKERRQ(ierr);
5342c71b3e2SJacob Faibussowitsch     PetscCheckFalse(info,PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve");
5354396437dSToby Isaac     if (PetscDefined(USE_COMPLEX)) {ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);}
5364396437dSToby Isaac     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
537bf5a80bcSToby Isaac     PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", "N", &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,mat->fwork,&mat->lfwork,&info));
5384396437dSToby Isaac     ierr = PetscFPTrapPop();CHKERRQ(ierr);
5392c71b3e2SJacob Faibussowitsch     PetscCheckFalse(info,PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform");
5404396437dSToby Isaac     if (PetscDefined(USE_COMPLEX)) {ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);}
5414396437dSToby Isaac   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"QR factored matrix cannot be used for transpose solve");
5424396437dSToby Isaac   ierr = PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank)));CHKERRQ(ierr);
5434396437dSToby Isaac   PetscFunctionReturn(0);
5444396437dSToby Isaac }
5454396437dSToby Isaac 
5464396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
5474396437dSToby Isaac {
5484396437dSToby Isaac   Mat_SeqDense      *mat = (Mat_SeqDense *) A->data;
5494905a7bcSToby Isaac   PetscScalar       *y;
5504905a7bcSToby Isaac   PetscBLASInt      m=0, k=0;
5514396437dSToby Isaac   PetscErrorCode    ierr;
5524905a7bcSToby Isaac 
5534905a7bcSToby Isaac   PetscFunctionBegin;
5544905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
5554905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
5564905a7bcSToby Isaac   if (k < m) {
5574396437dSToby Isaac     ierr = VecCopy(xx, mat->qrrhs);CHKERRQ(ierr);
5584396437dSToby Isaac     ierr = VecGetArray(mat->qrrhs,&y);CHKERRQ(ierr);
5594905a7bcSToby Isaac   } else {
5604396437dSToby Isaac     ierr = VecCopy(xx, yy);CHKERRQ(ierr);
5614905a7bcSToby Isaac     ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
5624905a7bcSToby Isaac   }
5634396437dSToby Isaac   *_y = y;
5644396437dSToby Isaac   *_k = k;
5654396437dSToby Isaac   *_m = m;
5664396437dSToby Isaac   PetscFunctionReturn(0);
5674396437dSToby Isaac }
5684396437dSToby Isaac 
5694396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
5704396437dSToby Isaac {
5714396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
57242e9364cSSatish Balay   PetscScalar    *y = NULL;
5734396437dSToby Isaac   PetscBLASInt   m, k;
5744396437dSToby Isaac   PetscErrorCode ierr;
5754396437dSToby Isaac 
5764396437dSToby Isaac   PetscFunctionBegin;
5774396437dSToby Isaac   y   = *_y;
5784396437dSToby Isaac   *_y = NULL;
5794396437dSToby Isaac   k   = *_k;
5804396437dSToby Isaac   m   = *_m;
5814905a7bcSToby Isaac   if (k < m) {
5824905a7bcSToby Isaac     PetscScalar *yv;
5834905a7bcSToby Isaac     ierr = VecGetArray(yy,&yv);CHKERRQ(ierr);
5844905a7bcSToby Isaac     ierr = PetscArraycpy(yv, y, k);CHKERRQ(ierr);
5854905a7bcSToby Isaac     ierr = VecRestoreArray(yy,&yv);CHKERRQ(ierr);
5864396437dSToby Isaac     ierr = VecRestoreArray(mat->qrrhs, &y);CHKERRQ(ierr);
5874905a7bcSToby Isaac   } else {
5884905a7bcSToby Isaac     ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
5894905a7bcSToby Isaac   }
5904905a7bcSToby Isaac   PetscFunctionReturn(0);
5914905a7bcSToby Isaac }
5924905a7bcSToby Isaac 
5934396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy)
5944396437dSToby Isaac {
59542e9364cSSatish Balay   PetscScalar    *y = NULL;
59642e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
5974396437dSToby Isaac   PetscErrorCode ierr;
5984396437dSToby Isaac 
5994396437dSToby Isaac   PetscFunctionBegin;
6004396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6014396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE);CHKERRQ(ierr);
6024396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6034396437dSToby Isaac   PetscFunctionReturn(0);
6044396437dSToby Isaac }
6054396437dSToby Isaac 
6064396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy)
6074396437dSToby Isaac {
60842e9364cSSatish Balay   PetscScalar    *y = NULL;
60942e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
6104396437dSToby Isaac   PetscErrorCode ierr;
6114396437dSToby Isaac 
6124396437dSToby Isaac   PetscFunctionBegin;
6134396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6144396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE);CHKERRQ(ierr);
6154396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6164396437dSToby Isaac   PetscFunctionReturn(0);
6174396437dSToby Isaac }
6184396437dSToby Isaac 
6194396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
6204396437dSToby Isaac {
621e54beecaSStefano Zampini   PetscScalar    *y = NULL;
622e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6234396437dSToby Isaac   PetscErrorCode ierr;
6244396437dSToby Isaac 
6254396437dSToby Isaac   PetscFunctionBegin;
6264396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6274396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE);CHKERRQ(ierr);
6284396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6294396437dSToby Isaac   PetscFunctionReturn(0);
6304396437dSToby Isaac }
6314396437dSToby Isaac 
6324396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
6334396437dSToby Isaac {
634e54beecaSStefano Zampini   PetscScalar    *y = NULL;
635e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6364396437dSToby Isaac   PetscErrorCode ierr;
6374396437dSToby Isaac 
6384396437dSToby Isaac   PetscFunctionBegin;
6394396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6404396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE);CHKERRQ(ierr);
6414396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6424396437dSToby Isaac   PetscFunctionReturn(0);
6434396437dSToby Isaac }
6444396437dSToby Isaac 
6454396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy)
6464396437dSToby Isaac {
647e54beecaSStefano Zampini   PetscScalar    *y = NULL;
648e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6494396437dSToby Isaac   PetscErrorCode ierr;
6504396437dSToby Isaac 
6514396437dSToby Isaac   PetscFunctionBegin;
6524396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6534396437dSToby Isaac   ierr = MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k);CHKERRQ(ierr);
6544396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6554396437dSToby Isaac   PetscFunctionReturn(0);
6564396437dSToby Isaac }
6574396437dSToby Isaac 
6584396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy)
6594396437dSToby Isaac {
66042e9364cSSatish Balay   PetscScalar    *y = NULL;
66142e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
6624396437dSToby Isaac   PetscErrorCode ierr;
6634396437dSToby Isaac 
6644396437dSToby Isaac   PetscFunctionBegin;
6654396437dSToby Isaac   ierr = MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6664396437dSToby Isaac   ierr = MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k);CHKERRQ(ierr);
6674396437dSToby Isaac   ierr = MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k);CHKERRQ(ierr);
6684396437dSToby Isaac   PetscFunctionReturn(0);
6694396437dSToby Isaac }
6704396437dSToby Isaac 
671bf5a80bcSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
6724905a7bcSToby Isaac {
6734905a7bcSToby Isaac   PetscErrorCode    ierr;
6744905a7bcSToby Isaac   const PetscScalar *b;
6754396437dSToby Isaac   PetscScalar       *y;
676bf5a80bcSToby Isaac   PetscInt          n, _ldb, _ldx;
677bf5a80bcSToby Isaac   PetscBLASInt      nrhs=0,m=0,k=0,ldb=0,ldx=0,ldy=0;
6784905a7bcSToby Isaac 
6794905a7bcSToby Isaac   PetscFunctionBegin;
6806280eecaSJose E. Roman   *_ldy=0; *_m=0; *_nrhs=0; *_k=0; *_y = NULL;
6814905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
6824905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
6834905a7bcSToby Isaac   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
6844905a7bcSToby Isaac   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
685bf5a80bcSToby Isaac   ierr = MatDenseGetLDA(B,&_ldb);CHKERRQ(ierr);
686bf5a80bcSToby Isaac   ierr = PetscBLASIntCast(_ldb, &ldb);CHKERRQ(ierr);
687bf5a80bcSToby Isaac   ierr = MatDenseGetLDA(X,&_ldx);CHKERRQ(ierr);
688bf5a80bcSToby Isaac   ierr = PetscBLASIntCast(_ldx, &ldx);CHKERRQ(ierr);
689bf5a80bcSToby Isaac   if (ldx < m) {
6904396437dSToby Isaac     ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
6914396437dSToby Isaac     ierr = PetscMalloc1(nrhs * m, &y);CHKERRQ(ierr);
692bf5a80bcSToby Isaac     if (ldb == m) {
693bf5a80bcSToby Isaac       ierr = PetscArraycpy(y,b,ldb*nrhs);CHKERRQ(ierr);
6944905a7bcSToby Isaac     } else {
6954905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
696bf5a80bcSToby Isaac         ierr = PetscArraycpy(&y[j*m],&b[j*ldb],m);CHKERRQ(ierr);
6974905a7bcSToby Isaac       }
6984905a7bcSToby Isaac     }
699bf5a80bcSToby Isaac     ldy = m;
7004396437dSToby Isaac     ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
7014905a7bcSToby Isaac   } else {
702bf5a80bcSToby Isaac     if (ldb == ldx) {
7034396437dSToby Isaac       ierr = MatCopy(B, X, SAME_NONZERO_PATTERN);CHKERRQ(ierr);
7044396437dSToby Isaac       ierr = MatDenseGetArray(X,&y);CHKERRQ(ierr);
7054905a7bcSToby Isaac     } else {
7064396437dSToby Isaac       ierr = MatDenseGetArray(X,&y);CHKERRQ(ierr);
7074396437dSToby Isaac       ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
7084905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
709bf5a80bcSToby Isaac         ierr = PetscArraycpy(&y[j*ldx],&b[j*ldb],m);CHKERRQ(ierr);
7104905a7bcSToby Isaac       }
7114396437dSToby Isaac       ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
7124905a7bcSToby Isaac     }
713bf5a80bcSToby Isaac     ldy = ldx;
7144905a7bcSToby Isaac   }
7154396437dSToby Isaac   *_y    = y;
716bf5a80bcSToby Isaac   *_ldy = ldy;
7174396437dSToby Isaac   *_k    = k;
7184396437dSToby Isaac   *_m    = m;
7194396437dSToby Isaac   *_nrhs = nrhs;
7204396437dSToby Isaac   PetscFunctionReturn(0);
7214396437dSToby Isaac }
7224396437dSToby Isaac 
723bf5a80bcSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
7244396437dSToby Isaac {
7254396437dSToby Isaac   PetscScalar       *y;
726bf5a80bcSToby Isaac   PetscInt          _ldx;
727bf5a80bcSToby Isaac   PetscBLASInt      k,ldy,nrhs,ldx=0;
7284396437dSToby Isaac   PetscErrorCode    ierr;
7294396437dSToby Isaac 
7304396437dSToby Isaac   PetscFunctionBegin;
7314396437dSToby Isaac   y    = *_y;
7324396437dSToby Isaac   *_y  = NULL;
7334396437dSToby Isaac   k    = *_k;
734bf5a80bcSToby Isaac   ldy = *_ldy;
7354396437dSToby Isaac   nrhs = *_nrhs;
736bf5a80bcSToby Isaac   ierr = MatDenseGetLDA(X,&_ldx);CHKERRQ(ierr);
737bf5a80bcSToby Isaac   ierr = PetscBLASIntCast(_ldx, &ldx);CHKERRQ(ierr);
738bf5a80bcSToby Isaac   if (ldx != ldy) {
7394905a7bcSToby Isaac     PetscScalar *xv;
7404905a7bcSToby Isaac     ierr = MatDenseGetArray(X,&xv);CHKERRQ(ierr);
7414905a7bcSToby Isaac     for (PetscInt j = 0; j < nrhs; j++) {
742bf5a80bcSToby Isaac       ierr = PetscArraycpy(&xv[j*ldx],&y[j*ldy],k);CHKERRQ(ierr);
7434905a7bcSToby Isaac     }
7444905a7bcSToby Isaac     ierr = MatDenseRestoreArray(X,&xv);CHKERRQ(ierr);
7454396437dSToby Isaac     ierr = PetscFree(y);CHKERRQ(ierr);
7464905a7bcSToby Isaac   } else {
7474396437dSToby Isaac     ierr = MatDenseRestoreArray(X,&y);CHKERRQ(ierr);
7484905a7bcSToby Isaac   }
74985e2c93fSHong Zhang   PetscFunctionReturn(0);
75085e2c93fSHong Zhang }
75185e2c93fSHong Zhang 
7524396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X)
7534396437dSToby Isaac {
7544396437dSToby Isaac   PetscScalar    *y;
755bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7564396437dSToby Isaac   PetscErrorCode ierr;
7574396437dSToby Isaac 
7584396437dSToby Isaac   PetscFunctionBegin;
759bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
760bf5a80bcSToby Isaac   ierr = MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE);CHKERRQ(ierr);
761bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
7624396437dSToby Isaac   PetscFunctionReturn(0);
7634396437dSToby Isaac }
7644396437dSToby Isaac 
7654396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X)
7664396437dSToby Isaac {
7674396437dSToby Isaac   PetscScalar    *y;
768bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7694396437dSToby Isaac   PetscErrorCode ierr;
7704396437dSToby Isaac 
7714396437dSToby Isaac   PetscFunctionBegin;
772bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
773bf5a80bcSToby Isaac   ierr = MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE);CHKERRQ(ierr);
774bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
7754396437dSToby Isaac   PetscFunctionReturn(0);
7764396437dSToby Isaac }
7774396437dSToby Isaac 
7784396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X)
7794396437dSToby Isaac {
7804396437dSToby Isaac   PetscScalar    *y;
781bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7824396437dSToby Isaac   PetscErrorCode ierr;
7834396437dSToby Isaac 
7844396437dSToby Isaac   PetscFunctionBegin;
785bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
786bf5a80bcSToby Isaac   ierr = MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE);CHKERRQ(ierr);
787bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
7884396437dSToby Isaac   PetscFunctionReturn(0);
7894396437dSToby Isaac }
7904396437dSToby Isaac 
7914396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X)
7924396437dSToby Isaac {
7934396437dSToby Isaac   PetscScalar    *y;
794bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7954396437dSToby Isaac   PetscErrorCode ierr;
7964396437dSToby Isaac 
7974396437dSToby Isaac   PetscFunctionBegin;
798bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
799bf5a80bcSToby Isaac   ierr = MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE);CHKERRQ(ierr);
800bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
8014396437dSToby Isaac   PetscFunctionReturn(0);
8024396437dSToby Isaac }
8034396437dSToby Isaac 
8044396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X)
8054396437dSToby Isaac {
8064396437dSToby Isaac   PetscScalar    *y;
807bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
8084396437dSToby Isaac   PetscErrorCode ierr;
8094396437dSToby Isaac 
8104396437dSToby Isaac   PetscFunctionBegin;
811bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
812bf5a80bcSToby Isaac   ierr = MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k);CHKERRQ(ierr);
813bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
8144396437dSToby Isaac   PetscFunctionReturn(0);
8154396437dSToby Isaac }
8164396437dSToby Isaac 
8174396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X)
8184396437dSToby Isaac {
8194396437dSToby Isaac   PetscScalar    *y;
820bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
8214396437dSToby Isaac   PetscErrorCode ierr;
8224396437dSToby Isaac 
8234396437dSToby Isaac   PetscFunctionBegin;
824bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
825bf5a80bcSToby Isaac   ierr = MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k);CHKERRQ(ierr);
826bf5a80bcSToby Isaac   ierr = MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k);CHKERRQ(ierr);
8274396437dSToby Isaac   PetscFunctionReturn(0);
8284396437dSToby Isaac }
8294396437dSToby Isaac 
83000121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
83100121966SStefano Zampini 
832db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
833db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
834db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
835ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
836db4efbfdSBarry Smith {
837db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
838db4efbfdSBarry Smith   PetscErrorCode ierr;
839db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
840db4efbfdSBarry Smith 
841db4efbfdSBarry Smith   PetscFunctionBegin;
842c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
843c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
844db4efbfdSBarry Smith   if (!mat->pivots) {
8458208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
8463bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
847db4efbfdSBarry Smith   }
848db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
8498e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
8508b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
8518e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
8528e57ea43SSatish Balay 
8532c71b3e2SJacob Faibussowitsch   PetscCheckFalse(info<0,PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
8542c71b3e2SJacob Faibussowitsch   PetscCheckFalse(info>0,PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
8558208b9aeSStefano Zampini 
8564396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
8574396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
8584396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8594396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
860d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
861db4efbfdSBarry Smith 
862f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
863f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
864f6224b95SHong Zhang 
865dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
866db4efbfdSBarry Smith   PetscFunctionReturn(0);
867db4efbfdSBarry Smith }
868db4efbfdSBarry Smith 
8694396437dSToby Isaac static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
8704396437dSToby Isaac {
8714396437dSToby Isaac   MatFactorInfo  info;
8724396437dSToby Isaac   PetscErrorCode ierr;
8734396437dSToby Isaac 
8744396437dSToby Isaac   PetscFunctionBegin;
8754396437dSToby Isaac   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
8764396437dSToby Isaac   ierr = (*fact->ops->lufactor)(fact,NULL,NULL,&info);CHKERRQ(ierr);
8774396437dSToby Isaac   PetscFunctionReturn(0);
8784396437dSToby Isaac }
8794396437dSToby Isaac 
8804396437dSToby Isaac PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
8814396437dSToby Isaac {
8824396437dSToby Isaac   PetscFunctionBegin;
8834396437dSToby Isaac   fact->preallocated           = PETSC_TRUE;
8844396437dSToby Isaac   fact->assembled              = PETSC_TRUE;
8854396437dSToby Isaac   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
8864396437dSToby Isaac   PetscFunctionReturn(0);
8874396437dSToby Isaac }
8884396437dSToby Isaac 
889a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
890ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
891db4efbfdSBarry Smith {
892db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
893db4efbfdSBarry Smith   PetscErrorCode ierr;
894c5df96a5SBarry Smith   PetscBLASInt   info,n;
895db4efbfdSBarry Smith 
896db4efbfdSBarry Smith   PetscFunctionBegin;
897c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
898db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
899a49dc2a2SStefano Zampini   if (A->spd) {
90000121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
9018b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
90200121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
903a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
904a49dc2a2SStefano Zampini   } else if (A->hermitian) {
905a49dc2a2SStefano Zampini     if (!mat->pivots) {
906a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
907a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
908a49dc2a2SStefano Zampini     }
909a49dc2a2SStefano Zampini     if (!mat->fwork) {
910a49dc2a2SStefano Zampini       PetscScalar dummy;
911a49dc2a2SStefano Zampini 
912a49dc2a2SStefano Zampini       mat->lfwork = -1;
91300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
914a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
91500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
916a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
917a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
918a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
919a49dc2a2SStefano Zampini     }
92000121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
921a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
92200121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
923a49dc2a2SStefano Zampini #endif
924a49dc2a2SStefano Zampini   } else { /* symmetric case */
925a49dc2a2SStefano Zampini     if (!mat->pivots) {
926a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
927a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
928a49dc2a2SStefano Zampini     }
929a49dc2a2SStefano Zampini     if (!mat->fwork) {
930a49dc2a2SStefano Zampini       PetscScalar dummy;
931a49dc2a2SStefano Zampini 
932a49dc2a2SStefano Zampini       mat->lfwork = -1;
93300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
934a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
93500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
936a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
937a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
938a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
939a49dc2a2SStefano Zampini     }
94000121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
941a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
94200121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
943a49dc2a2SStefano Zampini   }
9442c71b3e2SJacob Faibussowitsch   PetscCheckFalse(info,PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %" PetscInt_FMT,(PetscInt)info-1);
9458208b9aeSStefano Zampini 
9464396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
9474396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
9484396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
9494396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
950d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
9512205254eSKarl Rupp 
952f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
953f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
954f6224b95SHong Zhang 
955eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
956db4efbfdSBarry Smith   PetscFunctionReturn(0);
957db4efbfdSBarry Smith }
958db4efbfdSBarry Smith 
9594396437dSToby Isaac static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
960db4efbfdSBarry Smith {
961db4efbfdSBarry Smith   PetscErrorCode ierr;
962db4efbfdSBarry Smith   MatFactorInfo  info;
963db4efbfdSBarry Smith 
964db4efbfdSBarry Smith   PetscFunctionBegin;
965db4efbfdSBarry Smith   info.fill = 1.0;
9662205254eSKarl Rupp 
967c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
968f4259b30SLisandro Dalcin   ierr = (*fact->ops->choleskyfactor)(fact,NULL,&info);CHKERRQ(ierr);
969db4efbfdSBarry Smith   PetscFunctionReturn(0);
970db4efbfdSBarry Smith }
971db4efbfdSBarry Smith 
972ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
973db4efbfdSBarry Smith {
974db4efbfdSBarry Smith   PetscFunctionBegin;
975c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9761bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
977719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
978db4efbfdSBarry Smith   PetscFunctionReturn(0);
979db4efbfdSBarry Smith }
980db4efbfdSBarry Smith 
981bf5a80bcSToby Isaac PetscErrorCode MatQRFactor_SeqDense(Mat A,IS col,const MatFactorInfo *minfo)
9824905a7bcSToby Isaac {
9834905a7bcSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
9844905a7bcSToby Isaac   PetscErrorCode ierr;
9854905a7bcSToby Isaac   PetscBLASInt   n,m,info, min, max;
9864905a7bcSToby Isaac 
9874905a7bcSToby Isaac   PetscFunctionBegin;
9884905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
9894905a7bcSToby Isaac   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
9904396437dSToby Isaac   max = PetscMax(m, n);
9914396437dSToby Isaac   min = PetscMin(m, n);
9924905a7bcSToby Isaac   if (!mat->tau) {
9934396437dSToby Isaac     ierr = PetscMalloc1(min,&mat->tau);CHKERRQ(ierr);
9944396437dSToby Isaac     ierr = PetscLogObjectMemory((PetscObject)A,min*sizeof(PetscScalar));CHKERRQ(ierr);
9954396437dSToby Isaac   }
9964396437dSToby Isaac   if (!mat->pivots) {
997bf5a80bcSToby Isaac     ierr = PetscMalloc1(n,&mat->pivots);CHKERRQ(ierr);
998bf5a80bcSToby Isaac     ierr = PetscLogObjectMemory((PetscObject)A,n*sizeof(PetscScalar));CHKERRQ(ierr);
9994396437dSToby Isaac   }
10004396437dSToby Isaac   if (!mat->qrrhs) {
10014396437dSToby Isaac     ierr = MatCreateVecs(A, NULL, &(mat->qrrhs));CHKERRQ(ierr);
10024905a7bcSToby Isaac   }
10034905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
10044905a7bcSToby Isaac   if (!mat->fwork) {
10054905a7bcSToby Isaac     PetscScalar dummy;
10064905a7bcSToby Isaac 
10074905a7bcSToby Isaac     mat->lfwork = -1;
10084905a7bcSToby Isaac     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
10094905a7bcSToby Isaac     PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,&dummy,&mat->lfwork,&info));
10104905a7bcSToby Isaac     ierr = PetscFPTrapPop();CHKERRQ(ierr);
10114905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
10124905a7bcSToby Isaac     ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
10134905a7bcSToby Isaac     ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
10144905a7bcSToby Isaac   }
10154905a7bcSToby Isaac   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
10164905a7bcSToby Isaac   PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,mat->fwork,&mat->lfwork,&info));
10174905a7bcSToby Isaac   ierr = PetscFPTrapPop();CHKERRQ(ierr);
10182c71b3e2SJacob Faibussowitsch   PetscCheckFalse(info,PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to QR factorization");
10194905a7bcSToby 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
10204905a7bcSToby Isaac   mat->rank = min;
10214905a7bcSToby Isaac 
10224396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_QR;
10234396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_QR;
10244905a7bcSToby Isaac   A->factortype             = MAT_FACTOR_QR;
10254905a7bcSToby Isaac   if (m == n) {
10264396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
10274396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
10284905a7bcSToby Isaac   }
10294905a7bcSToby Isaac 
10304905a7bcSToby Isaac   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
10314905a7bcSToby Isaac   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
10324905a7bcSToby Isaac 
10334905a7bcSToby Isaac   ierr = PetscLogFlops(2.0*min*min*(max-min/3.0));CHKERRQ(ierr);
10344905a7bcSToby Isaac   PetscFunctionReturn(0);
10354905a7bcSToby Isaac }
10364905a7bcSToby Isaac 
10374905a7bcSToby Isaac static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
10384905a7bcSToby Isaac {
10394905a7bcSToby Isaac   PetscErrorCode ierr;
10404905a7bcSToby Isaac   MatFactorInfo  info;
10414905a7bcSToby Isaac 
10424905a7bcSToby Isaac   PetscFunctionBegin;
10434905a7bcSToby Isaac   info.fill = 1.0;
10444905a7bcSToby Isaac 
10454905a7bcSToby Isaac   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
1046bf5a80bcSToby Isaac   ierr = PetscUseMethod(fact,"MatQRFactor_C",(Mat,IS,const MatFactorInfo *),(fact,NULL,&info));CHKERRQ(ierr);
10474905a7bcSToby Isaac   PetscFunctionReturn(0);
10484905a7bcSToby Isaac }
10494905a7bcSToby Isaac 
1050bf5a80bcSToby Isaac PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
10514905a7bcSToby Isaac {
10524905a7bcSToby Isaac   PetscErrorCode ierr;
10534905a7bcSToby Isaac 
10544905a7bcSToby Isaac   PetscFunctionBegin;
10554905a7bcSToby Isaac   fact->assembled                  = PETSC_TRUE;
10564905a7bcSToby Isaac   fact->preallocated               = PETSC_TRUE;
10574905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)fact,"MatQRFactorNumeric_C",MatQRFactorNumeric_SeqDense);CHKERRQ(ierr);
10584905a7bcSToby Isaac   PetscFunctionReturn(0);
10594905a7bcSToby Isaac }
10604905a7bcSToby Isaac 
1061ca15aa20SStefano Zampini /* uses LAPACK */
1062cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
1063db4efbfdSBarry Smith {
1064db4efbfdSBarry Smith   PetscErrorCode ierr;
1065db4efbfdSBarry Smith 
1066db4efbfdSBarry Smith   PetscFunctionBegin;
1067ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
1068db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1069ca15aa20SStefano Zampini   ierr = MatSetType(*fact,MATDENSE);CHKERRQ(ierr);
107066e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
10712a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
1072db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
10732a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
1074bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) {
1075db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
1076bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_QR) {
1077bf5a80bcSToby Isaac     ierr = PetscObjectComposeFunction((PetscObject)(*fact),"MatQRFactorSymbolic_C",MatQRFactorSymbolic_SeqDense);CHKERRQ(ierr);
1078db4efbfdSBarry Smith   }
1079d5f3da31SBarry Smith   (*fact)->factortype = ftype;
108000c67f3bSHong Zhang 
108100c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
108200c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
10834ac6704cSBarry Smith   ierr = PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_LU]);CHKERRQ(ierr);
10844ac6704cSBarry Smith   ierr = PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ILU]);CHKERRQ(ierr);
10854ac6704cSBarry Smith   ierr = PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]);CHKERRQ(ierr);
10864ac6704cSBarry Smith   ierr = PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ICC]);CHKERRQ(ierr);
1087db4efbfdSBarry Smith   PetscFunctionReturn(0);
1088db4efbfdSBarry Smith }
1089db4efbfdSBarry Smith 
1090289bc588SBarry Smith /* ------------------------------------------------------------------*/
1091e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
1092289bc588SBarry Smith {
1093c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1094d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
1095d9ca1df4SBarry Smith   const PetscScalar *b;
1096dfbe8321SBarry Smith   PetscErrorCode    ierr;
1097d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
109823fff9afSBarry Smith   PetscBLASInt      o = 1,bm = 0;
1099289bc588SBarry Smith 
11003a40ed3dSBarry Smith   PetscFunctionBegin;
1101ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
11022c71b3e2SJacob Faibussowitsch   PetscCheckFalse(A->offloadmask == PETSC_OFFLOAD_GPU,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
1103ca15aa20SStefano Zampini #endif
1104422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
1105c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
1106289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
11073bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
11082dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
1109289bc588SBarry Smith   }
11101ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1111d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
1112b965ef7fSBarry Smith   its  = its*lits;
11132c71b3e2SJacob Faibussowitsch   PetscCheckFalse(its <= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %" PetscInt_FMT " and local its %" PetscInt_FMT " both positive",its,lits);
1114289bc588SBarry Smith   while (its--) {
1115fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1116289bc588SBarry Smith       for (i=0; i<m; i++) {
11173bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
111855a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1119289bc588SBarry Smith       }
1120289bc588SBarry Smith     }
1121fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1122289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
11233bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
112455a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1125289bc588SBarry Smith       }
1126289bc588SBarry Smith     }
1127289bc588SBarry Smith   }
1128d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
11291ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
11303a40ed3dSBarry Smith   PetscFunctionReturn(0);
1131289bc588SBarry Smith }
1132289bc588SBarry Smith 
1133289bc588SBarry Smith /* -----------------------------------------------------------------*/
1134ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
1135289bc588SBarry Smith {
1136c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1137d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
1138d9ca1df4SBarry Smith   PetscScalar       *y;
1139dfbe8321SBarry Smith   PetscErrorCode    ierr;
11400805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
1141ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
11423a40ed3dSBarry Smith 
11433a40ed3dSBarry Smith   PetscFunctionBegin;
1144c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1145c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
1146d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11472bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
11485ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11495ac36cfcSBarry Smith     PetscBLASInt i;
11505ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
11515ac36cfcSBarry Smith   } else {
11528b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
11535ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
11545ac36cfcSBarry Smith   }
1155d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
11562bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
11573a40ed3dSBarry Smith   PetscFunctionReturn(0);
1158289bc588SBarry Smith }
1159800995b7SMatthew Knepley 
1160ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
1161289bc588SBarry Smith {
1162c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1163d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
1164dfbe8321SBarry Smith   PetscErrorCode    ierr;
11650805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
1166d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
11673a40ed3dSBarry Smith 
11683a40ed3dSBarry Smith   PetscFunctionBegin;
1169c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1170c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
1171d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11722bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
11735ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11745ac36cfcSBarry Smith     PetscBLASInt i;
11755ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
11765ac36cfcSBarry Smith   } else {
11778b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
11785ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
11795ac36cfcSBarry Smith   }
1180d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
11812bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
11823a40ed3dSBarry Smith   PetscFunctionReturn(0);
1183289bc588SBarry Smith }
11846ee01492SSatish Balay 
1185ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1186289bc588SBarry Smith {
1187c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1188d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1189d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
1190dfbe8321SBarry Smith   PetscErrorCode    ierr;
11910805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
11923a40ed3dSBarry Smith 
11933a40ed3dSBarry Smith   PetscFunctionBegin;
1194c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1195c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
119617b127eeSStefano Zampini   ierr = VecCopy(zz,yy);CHKERRQ(ierr);
1197d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
1198d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
11991ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
12008b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
1201d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12021ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1203dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
12043a40ed3dSBarry Smith   PetscFunctionReturn(0);
1205289bc588SBarry Smith }
12066ee01492SSatish Balay 
1207ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1208289bc588SBarry Smith {
1209c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1210d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1211d9ca1df4SBarry Smith   PetscScalar       *y;
1212dfbe8321SBarry Smith   PetscErrorCode    ierr;
12130805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
121487828ca2SBarry Smith   PetscScalar       _DOne=1.0;
12153a40ed3dSBarry Smith 
12163a40ed3dSBarry Smith   PetscFunctionBegin;
1217c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
1218c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
121917b127eeSStefano Zampini   ierr = VecCopy(zz,yy);CHKERRQ(ierr);
1220d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
1221d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
12221ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
12238b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
1224d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
12251ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
1226dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
12273a40ed3dSBarry Smith   PetscFunctionReturn(0);
1228289bc588SBarry Smith }
1229289bc588SBarry Smith 
1230289bc588SBarry Smith /* -----------------------------------------------------------------*/
1231e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1232289bc588SBarry Smith {
1233c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
12346849ba73SBarry Smith   PetscErrorCode ierr;
123513f74950SBarry Smith   PetscInt       i;
123667e560aaSBarry Smith 
12373a40ed3dSBarry Smith   PetscFunctionBegin;
1238d0f46423SBarry Smith   *ncols = A->cmap->n;
1239289bc588SBarry Smith   if (cols) {
12403741e84bSPierre Jolivet     ierr = PetscMalloc1(A->cmap->n,cols);CHKERRQ(ierr);
1241d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
1242289bc588SBarry Smith   }
1243289bc588SBarry Smith   if (vals) {
1244ca15aa20SStefano Zampini     const PetscScalar *v;
1245ca15aa20SStefano Zampini 
1246ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
12473741e84bSPierre Jolivet     ierr = PetscMalloc1(A->cmap->n,vals);CHKERRQ(ierr);
1248ca15aa20SStefano Zampini     v   += row;
1249d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
1250ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1251289bc588SBarry Smith   }
12523a40ed3dSBarry Smith   PetscFunctionReturn(0);
1253289bc588SBarry Smith }
12546ee01492SSatish Balay 
1255e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1256289bc588SBarry Smith {
1257dfbe8321SBarry Smith   PetscErrorCode ierr;
12586e111a19SKarl Rupp 
1259606d414cSSatish Balay   PetscFunctionBegin;
1260cb4a9cd9SHong Zhang   if (ncols) *ncols = 0;
1261606d414cSSatish Balay   if (cols) { ierr = PetscFree(*cols);CHKERRQ(ierr); }
1262606d414cSSatish Balay   if (vals) { ierr = PetscFree(*vals);CHKERRQ(ierr); }
12633a40ed3dSBarry Smith   PetscFunctionReturn(0);
1264289bc588SBarry Smith }
1265289bc588SBarry Smith /* ----------------------------------------------------------------*/
1266e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
1267289bc588SBarry Smith {
1268c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
1269ca15aa20SStefano Zampini   PetscScalar      *av;
127013f74950SBarry Smith   PetscInt         i,j,idx=0;
1271ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1272c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1273ca15aa20SStefano Zampini #endif
1274ca15aa20SStefano Zampini   PetscErrorCode   ierr;
1275d6dfbf8fSBarry Smith 
12763a40ed3dSBarry Smith   PetscFunctionBegin;
1277ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&av);CHKERRQ(ierr);
1278289bc588SBarry Smith   if (!mat->roworiented) {
1279dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1280289bc588SBarry Smith       for (j=0; j<n; j++) {
1281cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
12826bdcaf15SBarry Smith         PetscCheck(indexn[j] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT,indexn[j],A->cmap->n-1);
1283289bc588SBarry Smith         for (i=0; i<m; i++) {
1284cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
12856bdcaf15SBarry Smith           PetscCheck(indexm[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT,indexm[i],A->rmap->n-1);
1286ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1287289bc588SBarry Smith         }
1288289bc588SBarry Smith       }
12893a40ed3dSBarry Smith     } else {
1290289bc588SBarry Smith       for (j=0; j<n; j++) {
1291cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
12926bdcaf15SBarry Smith         PetscCheck(indexn[j] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT,indexn[j],A->cmap->n-1);
1293289bc588SBarry Smith         for (i=0; i<m; i++) {
1294cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
12956bdcaf15SBarry Smith           PetscCheck(indexm[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT,indexm[i],A->rmap->n-1);
1296ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1297289bc588SBarry Smith         }
1298289bc588SBarry Smith       }
1299289bc588SBarry Smith     }
13003a40ed3dSBarry Smith   } else {
1301dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1302e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
1303cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
13046bdcaf15SBarry Smith         PetscCheck(indexm[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT,indexm[i],A->rmap->n-1);
1305e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
1306cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
13076bdcaf15SBarry Smith           PetscCheck(indexn[j] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT,indexn[j],A->cmap->n-1);
1308ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1309e8d4e0b9SBarry Smith         }
1310e8d4e0b9SBarry Smith       }
13113a40ed3dSBarry Smith     } else {
1312289bc588SBarry Smith       for (i=0; i<m; i++) {
1313cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
13146bdcaf15SBarry Smith         PetscCheck(indexm[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT,indexm[i],A->rmap->n-1);
1315289bc588SBarry Smith         for (j=0; j<n; j++) {
1316cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
13176bdcaf15SBarry Smith           PetscCheck(indexn[j] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT,indexn[j],A->cmap->n-1);
1318ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1319289bc588SBarry Smith         }
1320289bc588SBarry Smith       }
1321289bc588SBarry Smith     }
1322e8d4e0b9SBarry Smith   }
1323ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
1324ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1325c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
1326c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1327ca15aa20SStefano Zampini #endif
1328ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&av);CHKERRQ(ierr);
1329ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1330c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1331ca15aa20SStefano Zampini #endif
13323a40ed3dSBarry Smith   PetscFunctionReturn(0);
1333289bc588SBarry Smith }
1334e8d4e0b9SBarry Smith 
1335e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1336ae80bb75SLois Curfman McInnes {
1337ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1338ca15aa20SStefano Zampini   const PetscScalar *vv;
133913f74950SBarry Smith   PetscInt          i,j;
1340ca15aa20SStefano Zampini   PetscErrorCode    ierr;
1341ae80bb75SLois Curfman McInnes 
13423a40ed3dSBarry Smith   PetscFunctionBegin;
1343ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1344ae80bb75SLois Curfman McInnes   /* row-oriented output */
1345ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
134697e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
13472c71b3e2SJacob Faibussowitsch     PetscCheckFalse(indexm[i] >= A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %" PetscInt_FMT " requested larger than number rows %" PetscInt_FMT,indexm[i],A->rmap->n);
1348ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
13496f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
13502c71b3e2SJacob Faibussowitsch       PetscCheckFalse(indexn[j] >= A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column %" PetscInt_FMT " requested larger than number columns %" PetscInt_FMT,indexn[j],A->cmap->n);
1351ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1352ae80bb75SLois Curfman McInnes     }
1353ae80bb75SLois Curfman McInnes   }
1354ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
13553a40ed3dSBarry Smith   PetscFunctionReturn(0);
1356ae80bb75SLois Curfman McInnes }
1357ae80bb75SLois Curfman McInnes 
1358289bc588SBarry Smith /* -----------------------------------------------------------------*/
1359289bc588SBarry Smith 
13608491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1361aabbc4fbSShri Abhyankar {
1362aabbc4fbSShri Abhyankar   PetscErrorCode    ierr;
13638491ab44SLisandro Dalcin   PetscBool         skipHeader;
13648491ab44SLisandro Dalcin   PetscViewerFormat format;
13658491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
13668491ab44SLisandro Dalcin   const PetscScalar *v;
13678491ab44SLisandro Dalcin   PetscScalar       *vwork;
1368aabbc4fbSShri Abhyankar 
1369aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13708491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
13718491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
13728491ab44SLisandro Dalcin   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
13738491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1374aabbc4fbSShri Abhyankar 
13758491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
13768491ab44SLisandro Dalcin 
13778491ab44SLisandro Dalcin   /* write matrix header */
13788491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
13798491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
13808491ab44SLisandro Dalcin   if (!skipHeader) {ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);}
13818491ab44SLisandro Dalcin 
13828491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
13838491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13848491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
13858491ab44SLisandro Dalcin     /* store row lengths for each row */
13868491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
13878491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
13888491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
13898491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13908491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
13918491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
13928491ab44SLisandro Dalcin         iwork[k] = j;
13938491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
13948491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
13958491ab44SLisandro Dalcin   }
13968491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13978491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
13988491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
13998491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
14008491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
14018491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
14028491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
14038491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
14048491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
14058491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
14068491ab44SLisandro Dalcin   PetscFunctionReturn(0);
14078491ab44SLisandro Dalcin }
14088491ab44SLisandro Dalcin 
14098491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
14108491ab44SLisandro Dalcin {
14118491ab44SLisandro Dalcin   PetscErrorCode ierr;
14128491ab44SLisandro Dalcin   PetscBool      skipHeader;
14138491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
14148491ab44SLisandro Dalcin   PetscInt       rows,cols;
14158491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
14168491ab44SLisandro Dalcin 
14178491ab44SLisandro Dalcin   PetscFunctionBegin;
14188491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
14198491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
14208491ab44SLisandro Dalcin 
14218491ab44SLisandro Dalcin   if (!skipHeader) {
14228491ab44SLisandro Dalcin     ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
14232c71b3e2SJacob Faibussowitsch     PetscCheckFalse(header[0] != MAT_FILE_CLASSID,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
14248491ab44SLisandro Dalcin     M = header[1]; N = header[2];
14252c71b3e2SJacob Faibussowitsch     PetscCheckFalse(M < 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%" PetscInt_FMT ") in file is negative",M);
14262c71b3e2SJacob Faibussowitsch     PetscCheckFalse(N < 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%" PetscInt_FMT ") in file is negative",N);
14278491ab44SLisandro Dalcin     nz = header[3];
14282c71b3e2SJacob Faibussowitsch     PetscCheckFalse(nz != MATRIX_BINARY_FORMAT_DENSE && nz < 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %" PetscInt_FMT " in file",nz);
1429aabbc4fbSShri Abhyankar   } else {
14308491ab44SLisandro Dalcin     ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
14312c71b3e2SJacob Faibussowitsch     PetscCheckFalse(M < 0 || N < 0,PETSC_COMM_SELF,PETSC_ERR_USER,"Matrix binary file header was skipped, thus the user must specify the global sizes of input matrix");
14328491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1433e6324fbbSBarry Smith   }
1434aabbc4fbSShri Abhyankar 
14358491ab44SLisandro Dalcin   /* setup global sizes if not set */
14368491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
14378491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
14388491ab44SLisandro Dalcin   ierr = MatSetUp(mat);CHKERRQ(ierr);
14398491ab44SLisandro Dalcin   /* check if global sizes are correct */
14408491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
14412c71b3e2SJacob Faibussowitsch   PetscCheckFalse(M != rows || N != cols,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different sizes (%" PetscInt_FMT ", %" PetscInt_FMT ") than the input matrix (%" PetscInt_FMT ", %" PetscInt_FMT ")",M,N,rows,cols);
1442aabbc4fbSShri Abhyankar 
14438491ab44SLisandro Dalcin   ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
14448491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
14458491ab44SLisandro Dalcin   ierr = MatDenseGetArray(mat,&v);CHKERRQ(ierr);
14468491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
14478491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
14488491ab44SLisandro Dalcin     PetscInt nnz = m*N;
14498491ab44SLisandro Dalcin     /* read in matrix values */
14508491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&vwork);CHKERRQ(ierr);
14518491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
14528491ab44SLisandro Dalcin     /* store values in column major order */
14538491ab44SLisandro Dalcin     for (j=0; j<N; j++)
14548491ab44SLisandro Dalcin       for (i=0; i<m; i++)
14558491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
14568491ab44SLisandro Dalcin     ierr = PetscFree(vwork);CHKERRQ(ierr);
14578491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14588491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14598491ab44SLisandro Dalcin     /* read in row lengths */
14608491ab44SLisandro Dalcin     ierr = PetscMalloc1(m,&rlens);CHKERRQ(ierr);
14618491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
14628491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
14638491ab44SLisandro Dalcin     /* read in column indices and values */
14648491ab44SLisandro Dalcin     ierr = PetscMalloc2(nnz,&icols,nnz,&vwork);CHKERRQ(ierr);
14658491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
14668491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
14678491ab44SLisandro Dalcin     /* store values in column major order */
14688491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
14698491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
14708491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
14718491ab44SLisandro Dalcin     ierr = PetscFree(rlens);CHKERRQ(ierr);
14728491ab44SLisandro Dalcin     ierr = PetscFree2(icols,vwork);CHKERRQ(ierr);
1473aabbc4fbSShri Abhyankar   }
14748491ab44SLisandro Dalcin   ierr = MatDenseRestoreArray(mat,&v);CHKERRQ(ierr);
14758491ab44SLisandro Dalcin   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
14768491ab44SLisandro Dalcin   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1477aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1478aabbc4fbSShri Abhyankar }
1479aabbc4fbSShri Abhyankar 
1480eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1481eb91f321SVaclav Hapla {
1482eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1483eb91f321SVaclav Hapla   PetscErrorCode ierr;
1484eb91f321SVaclav Hapla 
1485eb91f321SVaclav Hapla   PetscFunctionBegin;
1486eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1487eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1488eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
1489eb91f321SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1490eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1491eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1492eb91f321SVaclav Hapla   if (isbinary) {
14938491ab44SLisandro Dalcin     ierr = MatLoad_Dense_Binary(newMat,viewer);CHKERRQ(ierr);
1494eb91f321SVaclav Hapla   } else if (ishdf5) {
1495eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
1496eb91f321SVaclav Hapla     ierr = MatLoad_Dense_HDF5(newMat,viewer);CHKERRQ(ierr);
1497eb91f321SVaclav Hapla #else
1498eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1499eb91f321SVaclav Hapla #endif
1500eb91f321SVaclav Hapla   } else {
150198921bdaSJacob Faibussowitsch     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"Viewer type %s not yet supported for reading %s matrices",((PetscObject)viewer)->type_name,((PetscObject)newMat)->type_name);
1502eb91f321SVaclav Hapla   }
1503eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1504eb91f321SVaclav Hapla }
1505eb91f321SVaclav Hapla 
15066849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1507289bc588SBarry Smith {
1508932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1509dfbe8321SBarry Smith   PetscErrorCode    ierr;
151013f74950SBarry Smith   PetscInt          i,j;
15112dcb1b2aSMatthew Knepley   const char        *name;
1512ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1513f3ef73ceSBarry Smith   PetscViewerFormat format;
15145f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1515ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
15165f481a85SSatish Balay #endif
1517932b0c3eSLois Curfman McInnes 
15183a40ed3dSBarry Smith   PetscFunctionBegin;
1519ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1520b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1521456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
15223a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1523fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1524d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1525d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1526ca15aa20SStefano Zampini       v    = av + i;
1527c0aa6a63SJacob Faibussowitsch       ierr = PetscViewerASCIIPrintf(viewer,"row %" PetscInt_FMT ":",i);CHKERRQ(ierr);
1528d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1529aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1530329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
1531c0aa6a63SJacob Faibussowitsch           ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1532329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
1533c0aa6a63SJacob Faibussowitsch           ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
15346831982aSBarry Smith         }
153580cd9d93SLois Curfman McInnes #else
15366831982aSBarry Smith         if (*v) {
1537c0aa6a63SJacob Faibussowitsch           ierr = PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",j,(double)*v);CHKERRQ(ierr);
15386831982aSBarry Smith         }
153980cd9d93SLois Curfman McInnes #endif
15401b807ce4Svictorle         v += a->lda;
154180cd9d93SLois Curfman McInnes       }
1542b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
154380cd9d93SLois Curfman McInnes     }
1544d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
15453a40ed3dSBarry Smith   } else {
1546d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1547aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
154847989497SBarry Smith     /* determine if matrix has all real values */
1549ca15aa20SStefano Zampini     v = av;
1550d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1551ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
155247989497SBarry Smith     }
155347989497SBarry Smith #endif
1554fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15553a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1556c0aa6a63SJacob Faibussowitsch       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1557c0aa6a63SJacob Faibussowitsch       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1558fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1559ffac6cdbSBarry Smith     }
1560ffac6cdbSBarry Smith 
1561d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1562ca15aa20SStefano Zampini       v = av + i;
1563d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1564aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
156547989497SBarry Smith         if (allreal) {
1566c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
156747989497SBarry Smith         } else {
1568c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
156947989497SBarry Smith         }
1570289bc588SBarry Smith #else
1571c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1572289bc588SBarry Smith #endif
15731b807ce4Svictorle         v += a->lda;
1574289bc588SBarry Smith       }
1575b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1576289bc588SBarry Smith     }
1577fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1578b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1579ffac6cdbSBarry Smith     }
1580d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1581da3a660dSBarry Smith   }
1582ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1583b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
15843a40ed3dSBarry Smith   PetscFunctionReturn(0);
1585289bc588SBarry Smith }
1586289bc588SBarry Smith 
15879804daf3SBarry Smith #include <petscdraw.h>
1588e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1589f1af5d2fSBarry Smith {
1590f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
15916849ba73SBarry Smith   PetscErrorCode    ierr;
1592383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1593383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1594ca15aa20SStefano Zampini   const PetscScalar *v;
1595b0a32e0cSBarry Smith   PetscViewer       viewer;
1596b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1597f3ef73ceSBarry Smith   PetscViewerFormat format;
1598f1af5d2fSBarry Smith 
1599f1af5d2fSBarry Smith   PetscFunctionBegin;
1600f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1601b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1602b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1603f1af5d2fSBarry Smith 
1604f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1605ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1606fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1607383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1608f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1609f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1610383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1611f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1612f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1613f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1614ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1615ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1616ca15aa20SStefano Zampini         else continue;
1617b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1618f1af5d2fSBarry Smith       }
1619f1af5d2fSBarry Smith     }
1620383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1621f1af5d2fSBarry Smith   } else {
1622f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1623f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1624b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1625b05fc000SLisandro Dalcin     PetscDraw popup;
1626b05fc000SLisandro Dalcin 
1627f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1628f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1629f1af5d2fSBarry Smith     }
1630383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1631b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
163245f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1633383922c3SLisandro Dalcin 
1634383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1635f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1636f1af5d2fSBarry Smith       x_l = j;
1637f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1638f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1639f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1640f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1641b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1642b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1643f1af5d2fSBarry Smith       }
1644f1af5d2fSBarry Smith     }
1645383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1646f1af5d2fSBarry Smith   }
1647ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1648f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1649f1af5d2fSBarry Smith }
1650f1af5d2fSBarry Smith 
1651e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1652f1af5d2fSBarry Smith {
1653b0a32e0cSBarry Smith   PetscDraw      draw;
1654ace3abfcSBarry Smith   PetscBool      isnull;
1655329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1656dfbe8321SBarry Smith   PetscErrorCode ierr;
1657f1af5d2fSBarry Smith 
1658f1af5d2fSBarry Smith   PetscFunctionBegin;
1659b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1660b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1661abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1662f1af5d2fSBarry Smith 
1663d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1664f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1665b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1666832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1667b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
16680298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1669832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1670f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1671f1af5d2fSBarry Smith }
1672f1af5d2fSBarry Smith 
1673dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1674932b0c3eSLois Curfman McInnes {
1675dfbe8321SBarry Smith   PetscErrorCode ierr;
1676ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1677932b0c3eSLois Curfman McInnes 
16783a40ed3dSBarry Smith   PetscFunctionBegin;
1679251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1680251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1681251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
1682c45a1595SBarry Smith   if (iascii) {
1683c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
16840f5bd95cSBarry Smith   } else if (isbinary) {
1685637a0070SStefano Zampini     ierr = MatView_Dense_Binary(A,viewer);CHKERRQ(ierr);
1686f1af5d2fSBarry Smith   } else if (isdraw) {
1687f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1688932b0c3eSLois Curfman McInnes   }
16893a40ed3dSBarry Smith   PetscFunctionReturn(0);
1690932b0c3eSLois Curfman McInnes }
1691289bc588SBarry Smith 
1692637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array)
1693d3042a70SBarry Smith {
1694d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1695d3042a70SBarry Smith 
1696d3042a70SBarry Smith   PetscFunctionBegin;
16972c71b3e2SJacob Faibussowitsch   PetscCheckFalse(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
16982c71b3e2SJacob Faibussowitsch   PetscCheckFalse(a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
16992c71b3e2SJacob Faibussowitsch   PetscCheckFalse(a->unplacedarray,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreArray() first");
1700d3042a70SBarry Smith   a->unplacedarray       = a->v;
1701d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1702d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1703637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1704ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1705c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1706ca15aa20SStefano Zampini #endif
1707d3042a70SBarry Smith   PetscFunctionReturn(0);
1708d3042a70SBarry Smith }
1709d3042a70SBarry Smith 
1710d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1711d3042a70SBarry Smith {
1712d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1713d3042a70SBarry Smith 
1714d3042a70SBarry Smith   PetscFunctionBegin;
17152c71b3e2SJacob Faibussowitsch   PetscCheckFalse(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
17162c71b3e2SJacob Faibussowitsch   PetscCheckFalse(a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1717d3042a70SBarry Smith   a->v             = a->unplacedarray;
1718d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1719d3042a70SBarry Smith   a->unplacedarray = NULL;
1720ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1721c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1722ca15aa20SStefano Zampini #endif
1723d3042a70SBarry Smith   PetscFunctionReturn(0);
1724d3042a70SBarry Smith }
1725d3042a70SBarry Smith 
1726d5ea218eSStefano Zampini static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A,const PetscScalar *array)
1727d5ea218eSStefano Zampini {
1728d5ea218eSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1729d5ea218eSStefano Zampini   PetscErrorCode ierr;
1730d5ea218eSStefano Zampini 
1731d5ea218eSStefano Zampini   PetscFunctionBegin;
17322c71b3e2SJacob Faibussowitsch   PetscCheckFalse(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
17332c71b3e2SJacob Faibussowitsch   PetscCheckFalse(a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1734d5ea218eSStefano Zampini   if (!a->user_alloc) { ierr = PetscFree(a->v);CHKERRQ(ierr); }
1735d5ea218eSStefano Zampini   a->v           = (PetscScalar*) array;
1736d5ea218eSStefano Zampini   a->user_alloc  = PETSC_FALSE;
1737d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1738d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1739d5ea218eSStefano Zampini #endif
1740d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1741d5ea218eSStefano Zampini }
1742d5ea218eSStefano Zampini 
1743ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1744289bc588SBarry Smith {
1745ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1746dfbe8321SBarry Smith   PetscErrorCode ierr;
174790f02eecSBarry Smith 
17483a40ed3dSBarry Smith   PetscFunctionBegin;
1749aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1750c0aa6a63SJacob Faibussowitsch   PetscLogObjectState((PetscObject)mat,"Rows %" PetscInt_FMT " Cols %" PetscInt_FMT,mat->rmap->n,mat->cmap->n);
1751a5a9c739SBarry Smith #endif
17524396437dSToby Isaac   ierr = VecDestroy(&(l->qrrhs));CHKERRQ(ierr);
17534905a7bcSToby Isaac   ierr = PetscFree(l->tau);CHKERRQ(ierr);
175405b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1755a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1756abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
17576857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1758637a0070SStefano Zampini   if (!l->unplaced_user_alloc) {ierr = PetscFree(l->unplacedarray);CHKERRQ(ierr);}
17592c71b3e2SJacob Faibussowitsch   PetscCheckFalse(l->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
17602c71b3e2SJacob Faibussowitsch   PetscCheckFalse(l->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
17616947451fSStefano Zampini   ierr = VecDestroy(&l->cvec);CHKERRQ(ierr);
17625ea7661aSPierre Jolivet   ierr = MatDestroy(&l->cmat);CHKERRQ(ierr);
1763bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1764dbd8c25aSHong Zhang 
1765f4259b30SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)mat,NULL);CHKERRQ(ierr);
17664905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatQRFactor_C",NULL);CHKERRQ(ierr);
176749a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1768ad16ce7aSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseSetLDA_C",NULL);CHKERRQ(ierr);
1769bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
177052c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
1771d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1772d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
1773d5ea218eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseReplaceArray_C",NULL);CHKERRQ(ierr);
177452c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL);CHKERRQ(ierr);
177552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL);CHKERRQ(ierr);
17766947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayWrite_C",NULL);CHKERRQ(ierr);
17776947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayWrite_C",NULL);CHKERRQ(ierr);
17788baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
17798baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17808baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
17818baccfbdSHong Zhang #endif
1782d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
1783d24d4204SJose E. Roman   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_scalapack_C",NULL);CHKERRQ(ierr);
1784d24d4204SJose E. Roman #endif
17852bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17862bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL);CHKERRQ(ierr);
17874222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL);CHKERRQ(ierr);
17884222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL);CHKERRQ(ierr);
17892bf066beSStefano Zampini #endif
1790bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
17914222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
17924222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL);CHKERRQ(ierr);
17934222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
17944222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
179552c5f739Sprj- 
179686aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
179786aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
17986947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVec_C",NULL);CHKERRQ(ierr);
17996947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVec_C",NULL);CHKERRQ(ierr);
18006947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecRead_C",NULL);CHKERRQ(ierr);
18016947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecRead_C",NULL);CHKERRQ(ierr);
18026947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecWrite_C",NULL);CHKERRQ(ierr);
18036947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecWrite_C",NULL);CHKERRQ(ierr);
18045ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetSubMatrix_C",NULL);CHKERRQ(ierr);
18055ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreSubMatrix_C",NULL);CHKERRQ(ierr);
18063a40ed3dSBarry Smith   PetscFunctionReturn(0);
1807289bc588SBarry Smith }
1808289bc588SBarry Smith 
1809e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1810289bc588SBarry Smith {
1811c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
18126849ba73SBarry Smith   PetscErrorCode ierr;
18136536e3caSStefano Zampini   PetscInt       k,j,m = A->rmap->n, M = mat->lda, n = A->cmap->n;
181487828ca2SBarry Smith   PetscScalar    *v,tmp;
181548b35521SBarry Smith 
18163a40ed3dSBarry Smith   PetscFunctionBegin;
18176536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
18186536e3caSStefano Zampini     if (m == n) { /* in place transpose */
1819ca15aa20SStefano Zampini       ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1820d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1821289bc588SBarry Smith         for (k=0; k<j; k++) {
18221b807ce4Svictorle           tmp        = v[j + k*M];
18231b807ce4Svictorle           v[j + k*M] = v[k + j*M];
18241b807ce4Svictorle           v[k + j*M] = tmp;
1825289bc588SBarry Smith         }
1826289bc588SBarry Smith       }
1827ca15aa20SStefano Zampini       ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
18286536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
18296536e3caSStefano Zampini       PetscScalar *v2;
18306536e3caSStefano Zampini       PetscLayout tmplayout;
18316536e3caSStefano Zampini 
18326536e3caSStefano Zampini       ierr = PetscMalloc1((size_t)m*n,&v2);CHKERRQ(ierr);
18336536e3caSStefano Zampini       ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
18346536e3caSStefano Zampini       for (j=0; j<n; j++) {
18356536e3caSStefano Zampini         for (k=0; k<m; k++) v2[j + (size_t)k*n] = v[k + (size_t)j*M];
18366536e3caSStefano Zampini       }
18376536e3caSStefano Zampini       ierr = PetscArraycpy(v,v2,(size_t)m*n);CHKERRQ(ierr);
18386536e3caSStefano Zampini       ierr = PetscFree(v2);CHKERRQ(ierr);
18396536e3caSStefano Zampini       ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
18406536e3caSStefano Zampini       /* cleanup size dependent quantities */
18416536e3caSStefano Zampini       ierr = VecDestroy(&mat->cvec);CHKERRQ(ierr);
18426536e3caSStefano Zampini       ierr = MatDestroy(&mat->cmat);CHKERRQ(ierr);
18436536e3caSStefano Zampini       ierr = PetscFree(mat->pivots);CHKERRQ(ierr);
18446536e3caSStefano Zampini       ierr = PetscFree(mat->fwork);CHKERRQ(ierr);
18456536e3caSStefano Zampini       ierr = MatDestroy(&mat->ptapwork);CHKERRQ(ierr);
18466536e3caSStefano Zampini       /* swap row/col layouts */
18476536e3caSStefano Zampini       mat->lda  = n;
18486536e3caSStefano Zampini       tmplayout = A->rmap;
18496536e3caSStefano Zampini       A->rmap   = A->cmap;
18506536e3caSStefano Zampini       A->cmap   = tmplayout;
18516536e3caSStefano Zampini     }
18523a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1853d3e5ee88SLois Curfman McInnes     Mat          tmat;
1854ec8511deSBarry Smith     Mat_SeqDense *tmatd;
185587828ca2SBarry Smith     PetscScalar  *v2;
1856af36a384SStefano Zampini     PetscInt     M2;
1857ea709b57SSatish Balay 
18586536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
1859ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1860d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
18617adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
18620298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1863ca15aa20SStefano Zampini     } else tmat = *matout;
1864ca15aa20SStefano Zampini 
1865ca15aa20SStefano Zampini     ierr  = MatDenseGetArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
1866ca15aa20SStefano Zampini     ierr  = MatDenseGetArray(tmat,&v2);CHKERRQ(ierr);
1867ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1868ca15aa20SStefano Zampini     M2    = tmatd->lda;
1869d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1870af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1871d3e5ee88SLois Curfman McInnes     }
1872ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(tmat,&v2);CHKERRQ(ierr);
1873ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
18746d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18756d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
18766536e3caSStefano Zampini     *matout = tmat;
187748b35521SBarry Smith   }
18783a40ed3dSBarry Smith   PetscFunctionReturn(0);
1879289bc588SBarry Smith }
1880289bc588SBarry Smith 
1881e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1882289bc588SBarry Smith {
1883c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1884c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1885ca15aa20SStefano Zampini   PetscInt          i;
1886ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
1887ca15aa20SStefano Zampini   PetscErrorCode    ierr;
18889ea5d5aeSSatish Balay 
18893a40ed3dSBarry Smith   PetscFunctionBegin;
1890d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1891d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1892ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A1,&v1);CHKERRQ(ierr);
1893ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A2,&v2);CHKERRQ(ierr);
1894ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
1895ca15aa20SStefano Zampini     ierr = PetscArraycmp(v1,v2,A1->rmap->n,flg);CHKERRQ(ierr);
1896ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1897ca15aa20SStefano Zampini     v1 += mat1->lda;
1898ca15aa20SStefano Zampini     v2 += mat2->lda;
18991b807ce4Svictorle   }
1900ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A1,&v1);CHKERRQ(ierr);
1901ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A2,&v2);CHKERRQ(ierr);
190277c4ece6SBarry Smith   *flg = PETSC_TRUE;
19033a40ed3dSBarry Smith   PetscFunctionReturn(0);
1904289bc588SBarry Smith }
1905289bc588SBarry Smith 
1906e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1907289bc588SBarry Smith {
1908c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
190913f74950SBarry Smith   PetscInt          i,n,len;
1910ca15aa20SStefano Zampini   PetscScalar       *x;
1911ca15aa20SStefano Zampini   const PetscScalar *vv;
1912ca15aa20SStefano Zampini   PetscErrorCode    ierr;
191344cd7ae7SLois Curfman McInnes 
19143a40ed3dSBarry Smith   PetscFunctionBegin;
19157a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
19161ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1917d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1918ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
19192c71b3e2SJacob Faibussowitsch   PetscCheckFalse(n != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
192044cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1921ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1922289bc588SBarry Smith   }
1923ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
19241ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
19253a40ed3dSBarry Smith   PetscFunctionReturn(0);
1926289bc588SBarry Smith }
1927289bc588SBarry Smith 
1928e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1929289bc588SBarry Smith {
1930c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1931f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1932ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1933dfbe8321SBarry Smith   PetscErrorCode    ierr;
1934d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
193555659b69SBarry Smith 
19363a40ed3dSBarry Smith   PetscFunctionBegin;
1937ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&vv);CHKERRQ(ierr);
193828988994SBarry Smith   if (ll) {
19397a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1940f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
19412c71b3e2SJacob Faibussowitsch     PetscCheckFalse(m != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1942da3a660dSBarry Smith     for (i=0; i<m; i++) {
1943da3a660dSBarry Smith       x = l[i];
1944ca15aa20SStefano Zampini       v = vv + i;
1945b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1946da3a660dSBarry Smith     }
1947f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1948eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1949da3a660dSBarry Smith   }
195028988994SBarry Smith   if (rr) {
19517a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1952f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
19532c71b3e2SJacob Faibussowitsch     PetscCheckFalse(n != A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1954da3a660dSBarry Smith     for (i=0; i<n; i++) {
1955da3a660dSBarry Smith       x = r[i];
1956ca15aa20SStefano Zampini       v = vv + i*mat->lda;
19572205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1958da3a660dSBarry Smith     }
1959f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1960eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1961da3a660dSBarry Smith   }
1962ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&vv);CHKERRQ(ierr);
19633a40ed3dSBarry Smith   PetscFunctionReturn(0);
1964289bc588SBarry Smith }
1965289bc588SBarry Smith 
1966ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1967289bc588SBarry Smith {
1968c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1969ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1970329f5518SBarry Smith   PetscReal         sum = 0.0;
1971*75f6d85dSStefano Zampini   PetscInt          lda, m=A->rmap->n,i,j;
1972efee365bSSatish Balay   PetscErrorCode    ierr;
197355659b69SBarry Smith 
19743a40ed3dSBarry Smith   PetscFunctionBegin;
1975ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
1976*75f6d85dSStefano Zampini   ierr = MatDenseGetLDA(A,&lda);CHKERRQ(ierr);
1977ca15aa20SStefano Zampini   v    = vv;
1978289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1979a5ce6ee0Svictorle     if (lda>m) {
1980d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1981ca15aa20SStefano Zampini         v = vv+j*lda;
1982a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1983a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1984a5ce6ee0Svictorle         }
1985a5ce6ee0Svictorle       }
1986a5ce6ee0Svictorle     } else {
1987570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1988570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
198973cf7048SBarry Smith       PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&cnt,v,&one));
1990570b7f6dSBarry Smith     }
1991570b7f6dSBarry Smith #else
1992d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1993329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1994289bc588SBarry Smith       }
1995a5ce6ee0Svictorle     }
19968f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1997570b7f6dSBarry Smith #endif
1998dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
19993a40ed3dSBarry Smith   } else if (type == NORM_1) {
2000064f8208SBarry Smith     *nrm = 0.0;
2001d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
2002ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
2003289bc588SBarry Smith       sum = 0.0;
2004d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
200533a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
2006289bc588SBarry Smith       }
2007064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
2008289bc588SBarry Smith     }
2009eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
20103a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2011064f8208SBarry Smith     *nrm = 0.0;
2012d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
2013ca15aa20SStefano Zampini       v   = vv + j;
2014289bc588SBarry Smith       sum = 0.0;
2015d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
20161b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
2017289bc588SBarry Smith       }
2018064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
2019289bc588SBarry Smith     }
2020eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
2021e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
2022ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
20233a40ed3dSBarry Smith   PetscFunctionReturn(0);
2024289bc588SBarry Smith }
2025289bc588SBarry Smith 
2026e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
2027289bc588SBarry Smith {
2028c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
202963ba0a88SBarry Smith   PetscErrorCode ierr;
203067e560aaSBarry Smith 
20313a40ed3dSBarry Smith   PetscFunctionBegin;
2032b5a2b587SKris Buschelman   switch (op) {
2033b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
20344e0d8c25SBarry Smith     aij->roworiented = flg;
2035b5a2b587SKris Buschelman     break;
2036512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
2037b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
20383971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
20398c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
204013fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
2041b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
2042b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
20430f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
20445021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
2045071fcb05SBarry Smith   case MAT_SORTED_FULL:
20467d3de750SJacob Faibussowitsch     ierr = PetscInfo(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
20475021d80fSJed Brown     break;
20485021d80fSJed Brown   case MAT_SPD:
204977e54ba9SKris Buschelman   case MAT_SYMMETRIC:
205077e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
20519a4540c5SBarry Smith   case MAT_HERMITIAN:
20529a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
20535021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
205477e54ba9SKris Buschelman     break;
2055b5a2b587SKris Buschelman   default:
205698921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
20573a40ed3dSBarry Smith   }
20583a40ed3dSBarry Smith   PetscFunctionReturn(0);
2059289bc588SBarry Smith }
2060289bc588SBarry Smith 
20613d8925e7SStefano Zampini PetscErrorCode MatZeroEntries_SeqDense(Mat A)
20626f0a148fSBarry Smith {
2063ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
20646849ba73SBarry Smith   PetscErrorCode ierr;
20653d8925e7SStefano Zampini   PetscInt       lda=l->lda,m=A->rmap->n,n=A->cmap->n,j;
2066ca15aa20SStefano Zampini   PetscScalar    *v;
20673a40ed3dSBarry Smith 
20683a40ed3dSBarry Smith   PetscFunctionBegin;
20693d8925e7SStefano Zampini   ierr = MatDenseGetArrayWrite(A,&v);CHKERRQ(ierr);
2070a5ce6ee0Svictorle   if (lda>m) {
20713d8925e7SStefano Zampini     for (j=0; j<n; j++) {
2072ca15aa20SStefano Zampini       ierr = PetscArrayzero(v+j*lda,m);CHKERRQ(ierr);
2073a5ce6ee0Svictorle     }
2074a5ce6ee0Svictorle   } else {
20753d8925e7SStefano Zampini     ierr = PetscArrayzero(v,PetscInt64Mult(m,n));CHKERRQ(ierr);
2076a5ce6ee0Svictorle   }
20773d8925e7SStefano Zampini   ierr = MatDenseRestoreArrayWrite(A,&v);CHKERRQ(ierr);
20783a40ed3dSBarry Smith   PetscFunctionReturn(0);
20796f0a148fSBarry Smith }
20806f0a148fSBarry Smith 
2081e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
20826f0a148fSBarry Smith {
208397b48c8fSBarry Smith   PetscErrorCode    ierr;
2084ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
2085b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
2086ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
208797b48c8fSBarry Smith   const PetscScalar *xx;
208855659b69SBarry Smith 
20893a40ed3dSBarry Smith   PetscFunctionBegin;
209076bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2091b9679d65SBarry Smith     for (i=0; i<N; i++) {
20922c71b3e2SJacob Faibussowitsch       PetscCheckFalse(rows[i] < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
20932c71b3e2SJacob Faibussowitsch       PetscCheckFalse(rows[i] >= A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %" PetscInt_FMT " requested to be zeroed greater than or equal number of rows %" PetscInt_FMT,rows[i],A->rmap->n);
2094b9679d65SBarry Smith     }
209576bd3646SJed Brown   }
2096ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
2097b9679d65SBarry Smith 
209897b48c8fSBarry Smith   /* fix right hand side if needed */
209997b48c8fSBarry Smith   if (x && b) {
210097b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
210197b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
21022205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
210397b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
210497b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
210597b48c8fSBarry Smith   }
210697b48c8fSBarry Smith 
2107ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
21086f0a148fSBarry Smith   for (i=0; i<N; i++) {
2109ca15aa20SStefano Zampini     slot = v + rows[i];
2110b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
21116f0a148fSBarry Smith   }
2112f4df32b1SMatthew Knepley   if (diag != 0.0) {
21132c71b3e2SJacob Faibussowitsch     PetscCheckFalse(A->rmap->n != A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
21146f0a148fSBarry Smith     for (i=0; i<N; i++) {
2115ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
2116f4df32b1SMatthew Knepley       *slot = diag;
21176f0a148fSBarry Smith     }
21186f0a148fSBarry Smith   }
2119ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
21203a40ed3dSBarry Smith   PetscFunctionReturn(0);
21216f0a148fSBarry Smith }
2122557bce09SLois Curfman McInnes 
212349a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
212449a6ff4bSBarry Smith {
212549a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
212649a6ff4bSBarry Smith 
212749a6ff4bSBarry Smith   PetscFunctionBegin;
212849a6ff4bSBarry Smith   *lda = mat->lda;
212949a6ff4bSBarry Smith   PetscFunctionReturn(0);
213049a6ff4bSBarry Smith }
213149a6ff4bSBarry Smith 
2132637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array)
213364e87e97SBarry Smith {
2134c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
21353a40ed3dSBarry Smith 
21363a40ed3dSBarry Smith   PetscFunctionBegin;
21372c71b3e2SJacob Faibussowitsch   PetscCheckFalse(mat->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
213864e87e97SBarry Smith   *array = mat->v;
21393a40ed3dSBarry Smith   PetscFunctionReturn(0);
214064e87e97SBarry Smith }
21410754003eSLois Curfman McInnes 
2142637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array)
2143ff14e315SSatish Balay {
21443a40ed3dSBarry Smith   PetscFunctionBegin;
2145*75f6d85dSStefano Zampini   if (array) *array = NULL;
21463a40ed3dSBarry Smith   PetscFunctionReturn(0);
2147ff14e315SSatish Balay }
21480754003eSLois Curfman McInnes 
21490f74d2c1SSatish Balay /*@
215049a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
215149a6ff4bSBarry Smith 
2152ad16ce7aSStefano Zampini    Not collective
215349a6ff4bSBarry Smith 
215449a6ff4bSBarry Smith    Input Parameter:
215549a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
215649a6ff4bSBarry Smith 
215749a6ff4bSBarry Smith    Output Parameter:
215849a6ff4bSBarry Smith .   lda - the leading dimension
215949a6ff4bSBarry Smith 
216049a6ff4bSBarry Smith    Level: intermediate
216149a6ff4bSBarry Smith 
2162ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseSetLDA()
216349a6ff4bSBarry Smith @*/
216449a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
216549a6ff4bSBarry Smith {
216649a6ff4bSBarry Smith   PetscErrorCode ierr;
216749a6ff4bSBarry Smith 
216849a6ff4bSBarry Smith   PetscFunctionBegin;
2169d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2170d5ea218eSStefano Zampini   PetscValidPointer(lda,2);
2171*75f6d85dSStefano Zampini   MatCheckPreallocated(A,1);
217249a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
217349a6ff4bSBarry Smith   PetscFunctionReturn(0);
217449a6ff4bSBarry Smith }
217549a6ff4bSBarry Smith 
21760f74d2c1SSatish Balay /*@
2177ad16ce7aSStefano Zampini    MatDenseSetLDA - Sets the leading dimension of the array used by the dense matrix
2178ad16ce7aSStefano Zampini 
2179ad16ce7aSStefano Zampini    Not collective
2180ad16ce7aSStefano Zampini 
2181d8d19677SJose E. Roman    Input Parameters:
2182ad16ce7aSStefano Zampini +  mat - a MATSEQDENSE or MATMPIDENSE matrix
2183ad16ce7aSStefano Zampini -  lda - the leading dimension
2184ad16ce7aSStefano Zampini 
2185ad16ce7aSStefano Zampini    Level: intermediate
2186ad16ce7aSStefano Zampini 
2187ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetLDA()
2188ad16ce7aSStefano Zampini @*/
2189ad16ce7aSStefano Zampini PetscErrorCode  MatDenseSetLDA(Mat A,PetscInt lda)
2190ad16ce7aSStefano Zampini {
2191ad16ce7aSStefano Zampini   PetscErrorCode ierr;
2192ad16ce7aSStefano Zampini 
2193ad16ce7aSStefano Zampini   PetscFunctionBegin;
2194ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2195ad16ce7aSStefano Zampini   ierr = PetscTryMethod(A,"MatDenseSetLDA_C",(Mat,PetscInt),(A,lda));CHKERRQ(ierr);
2196ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2197ad16ce7aSStefano Zampini }
2198ad16ce7aSStefano Zampini 
2199ad16ce7aSStefano Zampini /*@C
22006947451fSStefano Zampini    MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored
220173a71a0fSBarry Smith 
22028572280aSBarry Smith    Logically Collective on Mat
220373a71a0fSBarry Smith 
220473a71a0fSBarry Smith    Input Parameter:
22056947451fSStefano Zampini .  mat - a dense matrix
220673a71a0fSBarry Smith 
220773a71a0fSBarry Smith    Output Parameter:
220873a71a0fSBarry Smith .   array - pointer to the data
220973a71a0fSBarry Smith 
221073a71a0fSBarry Smith    Level: intermediate
221173a71a0fSBarry Smith 
22126947451fSStefano Zampini .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
221373a71a0fSBarry Smith @*/
22148c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
221573a71a0fSBarry Smith {
221673a71a0fSBarry Smith   PetscErrorCode ierr;
221773a71a0fSBarry Smith 
221873a71a0fSBarry Smith   PetscFunctionBegin;
2219d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2220d5ea218eSStefano Zampini   PetscValidPointer(array,2);
22218c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
222273a71a0fSBarry Smith   PetscFunctionReturn(0);
222373a71a0fSBarry Smith }
222473a71a0fSBarry Smith 
2225dec5eb66SMatthew G Knepley /*@C
2226579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
222773a71a0fSBarry Smith 
22288572280aSBarry Smith    Logically Collective on Mat
22298572280aSBarry Smith 
22308572280aSBarry Smith    Input Parameters:
22316947451fSStefano Zampini +  mat - a dense matrix
2232a2b725a8SWilliam Gropp -  array - pointer to the data
22338572280aSBarry Smith 
22348572280aSBarry Smith    Level: intermediate
22358572280aSBarry Smith 
22366947451fSStefano Zampini .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
22378572280aSBarry Smith @*/
22388572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
22398572280aSBarry Smith {
22408572280aSBarry Smith   PetscErrorCode ierr;
22418572280aSBarry Smith 
22428572280aSBarry Smith   PetscFunctionBegin;
2243d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2244d5ea218eSStefano Zampini   PetscValidPointer(array,2);
22458572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
22468572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
2247637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
2248637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2249637a0070SStefano Zampini #endif
22508572280aSBarry Smith   PetscFunctionReturn(0);
22518572280aSBarry Smith }
22528572280aSBarry Smith 
22538572280aSBarry Smith /*@C
22546947451fSStefano Zampini    MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored
22558572280aSBarry Smith 
22568572280aSBarry Smith    Not Collective
22578572280aSBarry Smith 
22588572280aSBarry Smith    Input Parameter:
22596947451fSStefano Zampini .  mat - a dense matrix
22608572280aSBarry Smith 
22618572280aSBarry Smith    Output Parameter:
22628572280aSBarry Smith .   array - pointer to the data
22638572280aSBarry Smith 
22648572280aSBarry Smith    Level: intermediate
22658572280aSBarry Smith 
22666947451fSStefano Zampini .seealso: MatDenseRestoreArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
22678572280aSBarry Smith @*/
22688572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
22698572280aSBarry Smith {
22708572280aSBarry Smith   PetscErrorCode ierr;
22718572280aSBarry Smith 
22728572280aSBarry Smith   PetscFunctionBegin;
2273d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2274d5ea218eSStefano Zampini   PetscValidPointer(array,2);
22758572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
22768572280aSBarry Smith   PetscFunctionReturn(0);
22778572280aSBarry Smith }
22788572280aSBarry Smith 
22798572280aSBarry Smith /*@C
22806947451fSStefano Zampini    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead()
22818572280aSBarry Smith 
228273a71a0fSBarry Smith    Not Collective
228373a71a0fSBarry Smith 
228473a71a0fSBarry Smith    Input Parameters:
22856947451fSStefano Zampini +  mat - a dense matrix
2286a2b725a8SWilliam Gropp -  array - pointer to the data
228773a71a0fSBarry Smith 
228873a71a0fSBarry Smith    Level: intermediate
228973a71a0fSBarry Smith 
22906947451fSStefano Zampini .seealso: MatDenseGetArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
229173a71a0fSBarry Smith @*/
22928572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
229373a71a0fSBarry Smith {
229473a71a0fSBarry Smith   PetscErrorCode ierr;
229573a71a0fSBarry Smith 
229673a71a0fSBarry Smith   PetscFunctionBegin;
2297d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2298d5ea218eSStefano Zampini   PetscValidPointer(array,2);
22998572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
230073a71a0fSBarry Smith   PetscFunctionReturn(0);
230173a71a0fSBarry Smith }
230273a71a0fSBarry Smith 
23036947451fSStefano Zampini /*@C
23046947451fSStefano Zampini    MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored
23056947451fSStefano Zampini 
23066947451fSStefano Zampini    Not Collective
23076947451fSStefano Zampini 
23086947451fSStefano Zampini    Input Parameter:
23096947451fSStefano Zampini .  mat - a dense matrix
23106947451fSStefano Zampini 
23116947451fSStefano Zampini    Output Parameter:
23126947451fSStefano Zampini .   array - pointer to the data
23136947451fSStefano Zampini 
23146947451fSStefano Zampini    Level: intermediate
23156947451fSStefano Zampini 
23166947451fSStefano Zampini .seealso: MatDenseRestoreArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
23176947451fSStefano Zampini @*/
23186947451fSStefano Zampini PetscErrorCode  MatDenseGetArrayWrite(Mat A,PetscScalar **array)
23196947451fSStefano Zampini {
23206947451fSStefano Zampini   PetscErrorCode ierr;
23216947451fSStefano Zampini 
23226947451fSStefano Zampini   PetscFunctionBegin;
2323d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2324d5ea218eSStefano Zampini   PetscValidPointer(array,2);
23256947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
23266947451fSStefano Zampini   PetscFunctionReturn(0);
23276947451fSStefano Zampini }
23286947451fSStefano Zampini 
23296947451fSStefano Zampini /*@C
23306947451fSStefano Zampini    MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite()
23316947451fSStefano Zampini 
23326947451fSStefano Zampini    Not Collective
23336947451fSStefano Zampini 
23346947451fSStefano Zampini    Input Parameters:
23356947451fSStefano Zampini +  mat - a dense matrix
23366947451fSStefano Zampini -  array - pointer to the data
23376947451fSStefano Zampini 
23386947451fSStefano Zampini    Level: intermediate
23396947451fSStefano Zampini 
23406947451fSStefano Zampini .seealso: MatDenseGetArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
23416947451fSStefano Zampini @*/
23426947451fSStefano Zampini PetscErrorCode  MatDenseRestoreArrayWrite(Mat A,PetscScalar **array)
23436947451fSStefano Zampini {
23446947451fSStefano Zampini   PetscErrorCode ierr;
23456947451fSStefano Zampini 
23466947451fSStefano Zampini   PetscFunctionBegin;
2347d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2348d5ea218eSStefano Zampini   PetscValidPointer(array,2);
23496947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
23506947451fSStefano Zampini   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
23516947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
23526947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
23536947451fSStefano Zampini #endif
23546947451fSStefano Zampini   PetscFunctionReturn(0);
23556947451fSStefano Zampini }
23566947451fSStefano Zampini 
2357023c16fcSToby Isaac static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,MatReuse scall,Mat *B)
23580754003eSLois Curfman McInnes {
2359c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
23606849ba73SBarry Smith   PetscErrorCode ierr;
2361bf5a80bcSToby Isaac   PetscInt       i,j,nrows,ncols,ldb;
23625d0c19d7SBarry Smith   const PetscInt *irow,*icol;
236387828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
23640754003eSLois Curfman McInnes   Mat            newmat;
23650754003eSLois Curfman McInnes 
23663a40ed3dSBarry Smith   PetscFunctionBegin;
236778b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
236878b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
2369e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2370e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
23710754003eSLois Curfman McInnes 
2372182d2002SSatish Balay   /* Check submatrixcall */
2373182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
237413f74950SBarry Smith     PetscInt n_cols,n_rows;
2375182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
237621a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2377f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
2378c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
237921a2c019SBarry Smith     }
2380182d2002SSatish Balay     newmat = *B;
2381182d2002SSatish Balay   } else {
23820754003eSLois Curfman McInnes     /* Create and fill new matrix */
2383ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
2384f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
23857adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
23860298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
2387182d2002SSatish Balay   }
2388182d2002SSatish Balay 
2389182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
2390ca15aa20SStefano Zampini   ierr = MatDenseGetArray(newmat,&bv);CHKERRQ(ierr);
2391bf5a80bcSToby Isaac   ierr = MatDenseGetLDA(newmat,&ldb);CHKERRQ(ierr);
2392182d2002SSatish Balay   for (i=0; i<ncols; i++) {
23936de62eeeSBarry Smith     av = v + mat->lda*icol[i];
2394ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
2395bf5a80bcSToby Isaac     bv += ldb;
23960754003eSLois Curfman McInnes   }
2397ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(newmat,&bv);CHKERRQ(ierr);
2398182d2002SSatish Balay 
2399182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
24006d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24016d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
24020754003eSLois Curfman McInnes 
24030754003eSLois Curfman McInnes   /* Free work space */
240478b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
240578b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2406182d2002SSatish Balay   *B   = newmat;
24073a40ed3dSBarry Smith   PetscFunctionReturn(0);
24080754003eSLois Curfman McInnes }
24090754003eSLois Curfman McInnes 
24107dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2411905e6a2fSBarry Smith {
24126849ba73SBarry Smith   PetscErrorCode ierr;
241313f74950SBarry Smith   PetscInt       i;
2414905e6a2fSBarry Smith 
24153a40ed3dSBarry Smith   PetscFunctionBegin;
2416905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
24173741e84bSPierre Jolivet     ierr = PetscCalloc1(n,B);CHKERRQ(ierr);
2418905e6a2fSBarry Smith   }
2419905e6a2fSBarry Smith 
2420905e6a2fSBarry Smith   for (i=0; i<n; i++) {
2421023c16fcSToby Isaac     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],scall,&(*B)[i]);CHKERRQ(ierr);
2422905e6a2fSBarry Smith   }
24233a40ed3dSBarry Smith   PetscFunctionReturn(0);
2424905e6a2fSBarry Smith }
2425905e6a2fSBarry Smith 
2426e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2427c0aa2d19SHong Zhang {
2428c0aa2d19SHong Zhang   PetscFunctionBegin;
2429c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2430c0aa2d19SHong Zhang }
2431c0aa2d19SHong Zhang 
2432e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2433c0aa2d19SHong Zhang {
2434c0aa2d19SHong Zhang   PetscFunctionBegin;
2435c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2436c0aa2d19SHong Zhang }
2437c0aa2d19SHong Zhang 
2438a76f77c3SStefano Zampini PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
24394b0e389bSBarry Smith {
24404b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
24416849ba73SBarry Smith   PetscErrorCode    ierr;
2442ca15aa20SStefano Zampini   const PetscScalar *va;
2443ca15aa20SStefano Zampini   PetscScalar       *vb;
2444d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
24453a40ed3dSBarry Smith 
24463a40ed3dSBarry Smith   PetscFunctionBegin;
244733f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
244833f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
2449cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
24503a40ed3dSBarry Smith     PetscFunctionReturn(0);
24513a40ed3dSBarry Smith   }
24522c71b3e2SJacob Faibussowitsch   PetscCheckFalse(m != B->rmap->n || n != B->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
2453ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&va);CHKERRQ(ierr);
2454ca15aa20SStefano Zampini   ierr = MatDenseGetArray(B,&vb);CHKERRQ(ierr);
2455a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
24560dbb7854Svictorle     for (j=0; j<n; j++) {
2457ca15aa20SStefano Zampini       ierr = PetscArraycpy(vb+j*lda2,va+j*lda1,m);CHKERRQ(ierr);
2458a5ce6ee0Svictorle     }
2459a5ce6ee0Svictorle   } else {
2460ca15aa20SStefano Zampini     ierr = PetscArraycpy(vb,va,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2461a5ce6ee0Svictorle   }
2462ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(B,&vb);CHKERRQ(ierr);
2463ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&va);CHKERRQ(ierr);
2464ca15aa20SStefano Zampini   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2465ca15aa20SStefano Zampini   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2466273d9f13SBarry Smith   PetscFunctionReturn(0);
2467273d9f13SBarry Smith }
2468273d9f13SBarry Smith 
2469*75f6d85dSStefano Zampini PetscErrorCode MatSetUp_SeqDense(Mat A)
2470273d9f13SBarry Smith {
2471dfbe8321SBarry Smith   PetscErrorCode ierr;
2472273d9f13SBarry Smith 
2473273d9f13SBarry Smith   PetscFunctionBegin;
247418992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
247518992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
247618992e5dSStefano Zampini   if (!A->preallocated) {
2477f4259b30SLisandro Dalcin     ierr = MatSeqDenseSetPreallocation(A,NULL);CHKERRQ(ierr);
247818992e5dSStefano Zampini   }
24793a40ed3dSBarry Smith   PetscFunctionReturn(0);
24804b0e389bSBarry Smith }
24814b0e389bSBarry Smith 
2482ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2483ba337c44SJed Brown {
24844396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
2485ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
24864396437dSToby Isaac   PetscInt       min = PetscMin(A->rmap->n,A->cmap->n);
2487ca15aa20SStefano Zampini   PetscScalar    *aa;
2488ca15aa20SStefano Zampini   PetscErrorCode ierr;
2489ba337c44SJed Brown 
2490ba337c44SJed Brown   PetscFunctionBegin;
2491ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2492ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2493ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
24944396437dSToby Isaac   if (mat->tau) for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2495ba337c44SJed Brown   PetscFunctionReturn(0);
2496ba337c44SJed Brown }
2497ba337c44SJed Brown 
2498ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2499ba337c44SJed Brown {
2500ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2501ca15aa20SStefano Zampini   PetscScalar    *aa;
2502ca15aa20SStefano Zampini   PetscErrorCode ierr;
2503ba337c44SJed Brown 
2504ba337c44SJed Brown   PetscFunctionBegin;
2505ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2506ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2507ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2508ba337c44SJed Brown   PetscFunctionReturn(0);
2509ba337c44SJed Brown }
2510ba337c44SJed Brown 
2511ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2512ba337c44SJed Brown {
2513ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2514ca15aa20SStefano Zampini   PetscScalar    *aa;
2515ca15aa20SStefano Zampini   PetscErrorCode ierr;
2516ba337c44SJed Brown 
2517ba337c44SJed Brown   PetscFunctionBegin;
2518ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2519ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
2520ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2521ba337c44SJed Brown   PetscFunctionReturn(0);
2522ba337c44SJed Brown }
2523284134d9SBarry Smith 
2524a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
25254222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2526a9fe9ddaSSatish Balay {
2527ee16a9a1SHong Zhang   PetscErrorCode ierr;
2528d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
25297a3c3d58SStefano Zampini   PetscBool      cisdense;
2530a9fe9ddaSSatish Balay 
2531ee16a9a1SHong Zhang   PetscFunctionBegin;
25324222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
25337a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
25347a3c3d58SStefano Zampini   if (!cisdense) {
25357a3c3d58SStefano Zampini     PetscBool flg;
25367a3c3d58SStefano Zampini 
2537ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
25384222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
25397a3c3d58SStefano Zampini   }
254018992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2541ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2542ee16a9a1SHong Zhang }
2543a9fe9ddaSSatish Balay 
2544a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2545a9fe9ddaSSatish Balay {
25466718818eSStefano Zampini   Mat_SeqDense       *a=(Mat_SeqDense*)A->data,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
25470805154bSBarry Smith   PetscBLASInt       m,n,k;
2548ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2549ca15aa20SStefano Zampini   PetscScalar       *cv;
2550a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2551c2916339SPierre Jolivet   PetscErrorCode    ierr;
2552a9fe9ddaSSatish Balay 
2553a9fe9ddaSSatish Balay   PetscFunctionBegin;
25548208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
25558208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2556c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
255749d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
2558ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
2559ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
25606718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
2561ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
2562ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2563ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
2564ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
25656718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2566a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2567a9fe9ddaSSatish Balay }
2568a9fe9ddaSSatish Balay 
25694222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
257069f65d41SStefano Zampini {
257169f65d41SStefano Zampini   PetscErrorCode ierr;
257269f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
25737a3c3d58SStefano Zampini   PetscBool      cisdense;
257469f65d41SStefano Zampini 
257569f65d41SStefano Zampini   PetscFunctionBegin;
25764222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
25777a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
25787a3c3d58SStefano Zampini   if (!cisdense) {
25797a3c3d58SStefano Zampini     PetscBool flg;
25807a3c3d58SStefano Zampini 
2581ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
25824222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
25837a3c3d58SStefano Zampini   }
258418992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
258569f65d41SStefano Zampini   PetscFunctionReturn(0);
258669f65d41SStefano Zampini }
258769f65d41SStefano Zampini 
258869f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
258969f65d41SStefano Zampini {
259069f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
259169f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
259269f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
25936718818eSStefano Zampini   const PetscScalar *av,*bv;
25946718818eSStefano Zampini   PetscScalar       *cv;
259569f65d41SStefano Zampini   PetscBLASInt      m,n,k;
259669f65d41SStefano Zampini   PetscScalar       _DOne=1.0,_DZero=0.0;
259769f65d41SStefano Zampini   PetscErrorCode    ierr;
259869f65d41SStefano Zampini 
259969f65d41SStefano Zampini   PetscFunctionBegin;
260049d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
260149d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
260269f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
260349d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
26046718818eSStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
26056718818eSStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
26066718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
26076718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
26086718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
26096718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
26106718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2611ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
261269f65d41SStefano Zampini   PetscFunctionReturn(0);
261369f65d41SStefano Zampini }
261469f65d41SStefano Zampini 
26154222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2616a9fe9ddaSSatish Balay {
2617ee16a9a1SHong Zhang   PetscErrorCode ierr;
2618d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
26197a3c3d58SStefano Zampini   PetscBool      cisdense;
2620a9fe9ddaSSatish Balay 
2621ee16a9a1SHong Zhang   PetscFunctionBegin;
26224222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
26237a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
26247a3c3d58SStefano Zampini   if (!cisdense) {
26257a3c3d58SStefano Zampini     PetscBool flg;
26267a3c3d58SStefano Zampini 
2627ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
26284222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
26297a3c3d58SStefano Zampini   }
263018992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2631ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2632ee16a9a1SHong Zhang }
2633a9fe9ddaSSatish Balay 
263475648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2635a9fe9ddaSSatish Balay {
2636a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2637a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
2638a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
26396718818eSStefano Zampini   const PetscScalar *av,*bv;
26406718818eSStefano Zampini   PetscScalar       *cv;
26410805154bSBarry Smith   PetscBLASInt      m,n,k;
2642a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2643c5df96a5SBarry Smith   PetscErrorCode    ierr;
2644a9fe9ddaSSatish Balay 
2645a9fe9ddaSSatish Balay   PetscFunctionBegin;
26468208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
26478208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2648c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
264949d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
26506718818eSStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
26516718818eSStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
26526718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
26536718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
26546718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
26556718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
26566718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2657ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2658a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2659a9fe9ddaSSatish Balay }
2660985db425SBarry Smith 
26614222ddf1SHong Zhang /* ----------------------------------------------- */
26624222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
26634222ddf1SHong Zhang {
26644222ddf1SHong Zhang   PetscFunctionBegin;
26654222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
26664222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
26674222ddf1SHong Zhang   PetscFunctionReturn(0);
26684222ddf1SHong Zhang }
26694222ddf1SHong Zhang 
26704222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
26714222ddf1SHong Zhang {
26724222ddf1SHong Zhang   PetscFunctionBegin;
26734222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
26744222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
26754222ddf1SHong Zhang   PetscFunctionReturn(0);
26764222ddf1SHong Zhang }
26774222ddf1SHong Zhang 
26784222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
26794222ddf1SHong Zhang {
26804222ddf1SHong Zhang   PetscFunctionBegin;
26814222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
26824222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
26834222ddf1SHong Zhang   PetscFunctionReturn(0);
26844222ddf1SHong Zhang }
26854222ddf1SHong Zhang 
26864222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
26874222ddf1SHong Zhang {
26884222ddf1SHong Zhang   PetscErrorCode ierr;
26894222ddf1SHong Zhang   Mat_Product    *product = C->product;
26904222ddf1SHong Zhang 
26914222ddf1SHong Zhang   PetscFunctionBegin;
26924222ddf1SHong Zhang   switch (product->type) {
26934222ddf1SHong Zhang   case MATPRODUCT_AB:
26944222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AB(C);CHKERRQ(ierr);
26954222ddf1SHong Zhang     break;
26964222ddf1SHong Zhang   case MATPRODUCT_AtB:
26974222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AtB(C);CHKERRQ(ierr);
26984222ddf1SHong Zhang     break;
26994222ddf1SHong Zhang   case MATPRODUCT_ABt:
27004222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_ABt(C);CHKERRQ(ierr);
27014222ddf1SHong Zhang     break;
27026718818eSStefano Zampini   default:
27034222ddf1SHong Zhang     break;
27044222ddf1SHong Zhang   }
27054222ddf1SHong Zhang   PetscFunctionReturn(0);
27064222ddf1SHong Zhang }
27074222ddf1SHong Zhang /* ----------------------------------------------- */
27084222ddf1SHong Zhang 
2709e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2710985db425SBarry Smith {
2711985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2712985db425SBarry Smith   PetscErrorCode     ierr;
2713d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2714985db425SBarry Smith   PetscScalar        *x;
2715ca15aa20SStefano Zampini   const PetscScalar *aa;
2716985db425SBarry Smith 
2717985db425SBarry Smith   PetscFunctionBegin;
27182c71b3e2SJacob Faibussowitsch   PetscCheckFalse(A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2719985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2720985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2721ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
27222c71b3e2SJacob Faibussowitsch   PetscCheckFalse(p != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2723985db425SBarry Smith   for (i=0; i<m; i++) {
2724985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2725985db425SBarry Smith     for (j=1; j<n; j++) {
2726ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2727985db425SBarry Smith     }
2728985db425SBarry Smith   }
2729ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2730985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2731985db425SBarry Smith   PetscFunctionReturn(0);
2732985db425SBarry Smith }
2733985db425SBarry Smith 
2734e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2735985db425SBarry Smith {
2736985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2737985db425SBarry Smith   PetscErrorCode    ierr;
2738d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2739985db425SBarry Smith   PetscScalar       *x;
2740985db425SBarry Smith   PetscReal         atmp;
2741ca15aa20SStefano Zampini   const PetscScalar *aa;
2742985db425SBarry Smith 
2743985db425SBarry Smith   PetscFunctionBegin;
27442c71b3e2SJacob Faibussowitsch   PetscCheckFalse(A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2745985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2746985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2747ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
27482c71b3e2SJacob Faibussowitsch   PetscCheckFalse(p != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2749985db425SBarry Smith   for (i=0; i<m; i++) {
27509189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2751985db425SBarry Smith     for (j=1; j<n; j++) {
2752ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2753985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2754985db425SBarry Smith     }
2755985db425SBarry Smith   }
2756ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2757985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2758985db425SBarry Smith   PetscFunctionReturn(0);
2759985db425SBarry Smith }
2760985db425SBarry Smith 
2761e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2762985db425SBarry Smith {
2763985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2764985db425SBarry Smith   PetscErrorCode    ierr;
2765d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2766985db425SBarry Smith   PetscScalar       *x;
2767ca15aa20SStefano Zampini   const PetscScalar *aa;
2768985db425SBarry Smith 
2769985db425SBarry Smith   PetscFunctionBegin;
27702c71b3e2SJacob Faibussowitsch   PetscCheckFalse(A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2771ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2772985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2773985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
27742c71b3e2SJacob Faibussowitsch   PetscCheckFalse(p != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2775985db425SBarry Smith   for (i=0; i<m; i++) {
2776985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2777985db425SBarry Smith     for (j=1; j<n; j++) {
2778ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2779985db425SBarry Smith     }
2780985db425SBarry Smith   }
2781985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2782ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2783985db425SBarry Smith   PetscFunctionReturn(0);
2784985db425SBarry Smith }
2785985db425SBarry Smith 
2786637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
27878d0534beSBarry Smith {
27888d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
27898d0534beSBarry Smith   PetscErrorCode    ierr;
27908d0534beSBarry Smith   PetscScalar       *x;
2791ca15aa20SStefano Zampini   const PetscScalar *aa;
27928d0534beSBarry Smith 
27938d0534beSBarry Smith   PetscFunctionBegin;
27942c71b3e2SJacob Faibussowitsch   PetscCheckFalse(A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2795ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
27968d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2797ca15aa20SStefano Zampini   ierr = PetscArraycpy(x,aa+col*a->lda,A->rmap->n);CHKERRQ(ierr);
27988d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2799ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
28008d0534beSBarry Smith   PetscFunctionReturn(0);
28018d0534beSBarry Smith }
28028d0534beSBarry Smith 
2803857cbf51SRichard Tran Mills PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A,PetscInt type,PetscReal *reductions)
28040716a85fSBarry Smith {
28050716a85fSBarry Smith   PetscErrorCode    ierr;
28060716a85fSBarry Smith   PetscInt          i,j,m,n;
28071683a169SBarry Smith   const PetscScalar *a;
28080716a85fSBarry Smith 
28090716a85fSBarry Smith   PetscFunctionBegin;
28100716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2811a873a8cdSSam Reynolds   ierr = PetscArrayzero(reductions,n);CHKERRQ(ierr);
28121683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&a);CHKERRQ(ierr);
2813857cbf51SRichard Tran Mills   if (type == NORM_2) {
28140716a85fSBarry Smith     for (i=0; i<n; i++) {
28150716a85fSBarry Smith       for (j=0; j<m; j++) {
2816a873a8cdSSam Reynolds         reductions[i] += PetscAbsScalar(a[j]*a[j]);
28170716a85fSBarry Smith       }
28180716a85fSBarry Smith       a += m;
28190716a85fSBarry Smith     }
2820857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
28210716a85fSBarry Smith     for (i=0; i<n; i++) {
28220716a85fSBarry Smith       for (j=0; j<m; j++) {
2823a873a8cdSSam Reynolds         reductions[i] += PetscAbsScalar(a[j]);
28240716a85fSBarry Smith       }
28250716a85fSBarry Smith       a += m;
28260716a85fSBarry Smith     }
2827857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
28280716a85fSBarry Smith     for (i=0; i<n; i++) {
28290716a85fSBarry Smith       for (j=0; j<m; j++) {
2830a873a8cdSSam Reynolds         reductions[i] = PetscMax(PetscAbsScalar(a[j]),reductions[i]);
28310716a85fSBarry Smith       }
28320716a85fSBarry Smith       a += m;
28330716a85fSBarry Smith     }
2834857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
2835a873a8cdSSam Reynolds     for (i=0; i<n; i++) {
2836a873a8cdSSam Reynolds       for (j=0; j<m; j++) {
2837857cbf51SRichard Tran Mills         reductions[i] += PetscRealPart(a[j]);
2838a873a8cdSSam Reynolds       }
2839a873a8cdSSam Reynolds       a += m;
2840a873a8cdSSam Reynolds     }
2841857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2842857cbf51SRichard Tran Mills     for (i=0; i<n; i++) {
2843857cbf51SRichard Tran Mills       for (j=0; j<m; j++) {
2844857cbf51SRichard Tran Mills         reductions[i] += PetscImaginaryPart(a[j]);
2845857cbf51SRichard Tran Mills       }
2846857cbf51SRichard Tran Mills       a += m;
2847857cbf51SRichard Tran Mills     }
2848857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown reduction type");
28491683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&a);CHKERRQ(ierr);
2850857cbf51SRichard Tran Mills   if (type == NORM_2) {
2851a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
2852857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2853a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] /= m;
28540716a85fSBarry Smith   }
28550716a85fSBarry Smith   PetscFunctionReturn(0);
28560716a85fSBarry Smith }
28570716a85fSBarry Smith 
285873a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
285973a71a0fSBarry Smith {
286073a71a0fSBarry Smith   PetscErrorCode ierr;
286173a71a0fSBarry Smith   PetscScalar    *a;
2862637a0070SStefano Zampini   PetscInt       lda,m,n,i,j;
286373a71a0fSBarry Smith 
286473a71a0fSBarry Smith   PetscFunctionBegin;
286573a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
2866637a0070SStefano Zampini   ierr = MatDenseGetLDA(x,&lda);CHKERRQ(ierr);
28678c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
2868637a0070SStefano Zampini   for (j=0; j<n; j++) {
2869637a0070SStefano Zampini     for (i=0; i<m; i++) {
2870637a0070SStefano Zampini       ierr = PetscRandomGetValue(rctx,a+j*lda+i);CHKERRQ(ierr);
2871637a0070SStefano Zampini     }
287273a71a0fSBarry Smith   }
28738c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
287473a71a0fSBarry Smith   PetscFunctionReturn(0);
287573a71a0fSBarry Smith }
287673a71a0fSBarry Smith 
28773b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
28783b49f96aSBarry Smith {
28793b49f96aSBarry Smith   PetscFunctionBegin;
28803b49f96aSBarry Smith   *missing = PETSC_FALSE;
28813b49f96aSBarry Smith   PetscFunctionReturn(0);
28823b49f96aSBarry Smith }
288373a71a0fSBarry Smith 
2884ca15aa20SStefano Zampini /* vals is not const */
2885af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
288686aefd0dSHong Zhang {
2887ca15aa20SStefano Zampini   PetscErrorCode ierr;
288886aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2889ca15aa20SStefano Zampini   PetscScalar    *v;
289086aefd0dSHong Zhang 
289186aefd0dSHong Zhang   PetscFunctionBegin;
28922c71b3e2SJacob Faibussowitsch   PetscCheckFalse(A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2893ca15aa20SStefano Zampini   ierr  = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2894ca15aa20SStefano Zampini   *vals = v+col*a->lda;
2895ca15aa20SStefano Zampini   ierr  = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
289686aefd0dSHong Zhang   PetscFunctionReturn(0);
289786aefd0dSHong Zhang }
289886aefd0dSHong Zhang 
2899af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
290086aefd0dSHong Zhang {
290186aefd0dSHong Zhang   PetscFunctionBegin;
2902a5b23f4aSJose E. Roman   *vals = NULL; /* user cannot accidentally use the array later */
290386aefd0dSHong Zhang   PetscFunctionReturn(0);
290486aefd0dSHong Zhang }
2905abc3b08eSStefano Zampini 
2906289bc588SBarry Smith /* -------------------------------------------------------------------*/
2907a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2908905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2909905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2910905e6a2fSBarry Smith                                         MatMult_SeqDense,
291197304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
29127c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
29137c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2914f4259b30SLisandro Dalcin                                         NULL,
2915f4259b30SLisandro Dalcin                                         NULL,
2916f4259b30SLisandro Dalcin                                         NULL,
2917f4259b30SLisandro Dalcin                                 /* 10*/ NULL,
2918905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2919905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
292041f059aeSBarry Smith                                         MatSOR_SeqDense,
2921ec8511deSBarry Smith                                         MatTranspose_SeqDense,
292297304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2923905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2924905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2925905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2926905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2927c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2928c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2929905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2930905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2931d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2932f4259b30SLisandro Dalcin                                         NULL,
2933f4259b30SLisandro Dalcin                                         NULL,
2934f4259b30SLisandro Dalcin                                         NULL,
2935f4259b30SLisandro Dalcin                                         NULL,
29364994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2937f4259b30SLisandro Dalcin                                         NULL,
2938f4259b30SLisandro Dalcin                                         NULL,
2939f4259b30SLisandro Dalcin                                         NULL,
2940f4259b30SLisandro Dalcin                                         NULL,
2941d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2942f4259b30SLisandro Dalcin                                         NULL,
2943f4259b30SLisandro Dalcin                                         NULL,
2944f4259b30SLisandro Dalcin                                         NULL,
2945f4259b30SLisandro Dalcin                                         NULL,
2946d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
29477dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2948f4259b30SLisandro Dalcin                                         NULL,
29494b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2950a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2951d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2952a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
29537d68702bSBarry Smith                                         MatShift_Basic,
2954f4259b30SLisandro Dalcin                                         NULL,
29553f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
295673a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2957f4259b30SLisandro Dalcin                                         NULL,
2958f4259b30SLisandro Dalcin                                         NULL,
2959f4259b30SLisandro Dalcin                                         NULL,
2960f4259b30SLisandro Dalcin                                         NULL,
2961f4259b30SLisandro Dalcin                                 /* 54*/ NULL,
2962f4259b30SLisandro Dalcin                                         NULL,
2963f4259b30SLisandro Dalcin                                         NULL,
2964f4259b30SLisandro Dalcin                                         NULL,
2965f4259b30SLisandro Dalcin                                         NULL,
2966023c16fcSToby Isaac                                 /* 59*/ MatCreateSubMatrix_SeqDense,
2967e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2968e03a110bSBarry Smith                                         MatView_SeqDense,
2969f4259b30SLisandro Dalcin                                         NULL,
2970f4259b30SLisandro Dalcin                                         NULL,
2971f4259b30SLisandro Dalcin                                 /* 64*/ NULL,
2972f4259b30SLisandro Dalcin                                         NULL,
2973f4259b30SLisandro Dalcin                                         NULL,
2974f4259b30SLisandro Dalcin                                         NULL,
2975f4259b30SLisandro Dalcin                                         NULL,
2976d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
2977f4259b30SLisandro Dalcin                                         NULL,
2978f4259b30SLisandro Dalcin                                         NULL,
2979f4259b30SLisandro Dalcin                                         NULL,
2980f4259b30SLisandro Dalcin                                         NULL,
2981f4259b30SLisandro Dalcin                                 /* 74*/ NULL,
2982f4259b30SLisandro Dalcin                                         NULL,
2983f4259b30SLisandro Dalcin                                         NULL,
2984f4259b30SLisandro Dalcin                                         NULL,
2985f4259b30SLisandro Dalcin                                         NULL,
2986f4259b30SLisandro Dalcin                                 /* 79*/ NULL,
2987f4259b30SLisandro Dalcin                                         NULL,
2988f4259b30SLisandro Dalcin                                         NULL,
2989f4259b30SLisandro Dalcin                                         NULL,
29905bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2991637a0070SStefano Zampini                                         MatIsSymmetric_SeqDense,
29921cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2993f4259b30SLisandro Dalcin                                         NULL,
2994f4259b30SLisandro Dalcin                                         NULL,
2995f4259b30SLisandro Dalcin                                         NULL,
2996f4259b30SLisandro Dalcin                                 /* 89*/ NULL,
2997f4259b30SLisandro Dalcin                                         NULL,
2998a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2999f4259b30SLisandro Dalcin                                         NULL,
3000f4259b30SLisandro Dalcin                                         NULL,
3001f4259b30SLisandro Dalcin                                 /* 94*/ NULL,
3002f4259b30SLisandro Dalcin                                         NULL,
3003f4259b30SLisandro Dalcin                                         NULL,
300469f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
3005f4259b30SLisandro Dalcin                                         NULL,
30064222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
3007f4259b30SLisandro Dalcin                                         NULL,
3008f4259b30SLisandro Dalcin                                         NULL,
3009ba337c44SJed Brown                                         MatConjugate_SeqDense,
3010f4259b30SLisandro Dalcin                                         NULL,
3011f4259b30SLisandro Dalcin                                 /*104*/ NULL,
3012ba337c44SJed Brown                                         MatRealPart_SeqDense,
3013ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
3014f4259b30SLisandro Dalcin                                         NULL,
3015f4259b30SLisandro Dalcin                                         NULL,
3016f4259b30SLisandro Dalcin                                 /*109*/ NULL,
3017f4259b30SLisandro Dalcin                                         NULL,
30188d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
3019aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
30203b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
3021f4259b30SLisandro Dalcin                                 /*114*/ NULL,
3022f4259b30SLisandro Dalcin                                         NULL,
3023f4259b30SLisandro Dalcin                                         NULL,
3024f4259b30SLisandro Dalcin                                         NULL,
3025f4259b30SLisandro Dalcin                                         NULL,
3026f4259b30SLisandro Dalcin                                 /*119*/ NULL,
3027f4259b30SLisandro Dalcin                                         NULL,
3028f4259b30SLisandro Dalcin                                         NULL,
3029f4259b30SLisandro Dalcin                                         NULL,
3030f4259b30SLisandro Dalcin                                         NULL,
3031f4259b30SLisandro Dalcin                                 /*124*/ NULL,
3032a873a8cdSSam Reynolds                                         MatGetColumnReductions_SeqDense,
3033f4259b30SLisandro Dalcin                                         NULL,
3034f4259b30SLisandro Dalcin                                         NULL,
3035f4259b30SLisandro Dalcin                                         NULL,
3036f4259b30SLisandro Dalcin                                 /*129*/ NULL,
3037f4259b30SLisandro Dalcin                                         NULL,
3038f4259b30SLisandro Dalcin                                         NULL,
303975648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
3040f4259b30SLisandro Dalcin                                         NULL,
3041f4259b30SLisandro Dalcin                                 /*134*/ NULL,
3042f4259b30SLisandro Dalcin                                         NULL,
3043f4259b30SLisandro Dalcin                                         NULL,
3044f4259b30SLisandro Dalcin                                         NULL,
3045f4259b30SLisandro Dalcin                                         NULL,
3046f4259b30SLisandro Dalcin                                 /*139*/ NULL,
3047f4259b30SLisandro Dalcin                                         NULL,
3048f4259b30SLisandro Dalcin                                         NULL,
3049f4259b30SLisandro Dalcin                                         NULL,
3050f4259b30SLisandro Dalcin                                         NULL,
30514222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
3052f4259b30SLisandro Dalcin                                 /*145*/ NULL,
3053f4259b30SLisandro Dalcin                                         NULL,
3054f4259b30SLisandro Dalcin                                         NULL
3055985db425SBarry Smith };
305690ace30eSBarry Smith 
30574b828684SBarry Smith /*@C
3058fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
3059d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
3060d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
3061289bc588SBarry Smith 
3062d083f849SBarry Smith    Collective
3063db81eaa0SLois Curfman McInnes 
306420563c6bSBarry Smith    Input Parameters:
3065db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
30660c775827SLois Curfman McInnes .  m - number of rows
306718f449edSLois Curfman McInnes .  n - number of columns
30680298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
3069dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
307020563c6bSBarry Smith 
307120563c6bSBarry Smith    Output Parameter:
307244cd7ae7SLois Curfman McInnes .  A - the matrix
307320563c6bSBarry Smith 
3074b259b22eSLois Curfman McInnes    Notes:
307518f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
307618f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
30770298fd71SBarry Smith    set data=NULL.
307818f449edSLois Curfman McInnes 
3079027ccd11SLois Curfman McInnes    Level: intermediate
3080027ccd11SLois Curfman McInnes 
308169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
308220563c6bSBarry Smith @*/
30837087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
3084289bc588SBarry Smith {
3085dfbe8321SBarry Smith   PetscErrorCode ierr;
30863b2fbd54SBarry Smith 
30873a40ed3dSBarry Smith   PetscFunctionBegin;
3088f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
3089f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
3090273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
3091273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
3092273d9f13SBarry Smith   PetscFunctionReturn(0);
3093273d9f13SBarry Smith }
3094273d9f13SBarry Smith 
3095273d9f13SBarry Smith /*@C
3096273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
3097273d9f13SBarry Smith 
3098d083f849SBarry Smith    Collective
3099273d9f13SBarry Smith 
3100273d9f13SBarry Smith    Input Parameters:
31011c4f3114SJed Brown +  B - the matrix
31020298fd71SBarry Smith -  data - the array (or NULL)
3103273d9f13SBarry Smith 
3104273d9f13SBarry Smith    Notes:
3105273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
3106273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
3107284134d9SBarry Smith    need not call this routine.
3108273d9f13SBarry Smith 
3109273d9f13SBarry Smith    Level: intermediate
3110273d9f13SBarry Smith 
3111ad16ce7aSStefano Zampini .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatDenseSetLDA()
3112867c911aSBarry Smith 
3113273d9f13SBarry Smith @*/
31147087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
3115273d9f13SBarry Smith {
31164ac538c5SBarry Smith   PetscErrorCode ierr;
3117a23d5eceSKris Buschelman 
3118a23d5eceSKris Buschelman   PetscFunctionBegin;
3119d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
31204ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
3121a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3122a23d5eceSKris Buschelman }
3123a23d5eceSKris Buschelman 
31247087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
3125a23d5eceSKris Buschelman {
3126ad16ce7aSStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
3127dfbe8321SBarry Smith   PetscErrorCode ierr;
3128273d9f13SBarry Smith 
3129273d9f13SBarry Smith   PetscFunctionBegin;
31302c71b3e2SJacob Faibussowitsch   PetscCheckFalse(b->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
3131273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3132a868139aSShri Abhyankar 
313334ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
313434ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
313534ef9618SShri Abhyankar 
3136ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
313786d161a7SShri Abhyankar 
31389e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
31399e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
3140ad16ce7aSStefano Zampini     ierr = PetscCalloc1((size_t)b->lda*B->cmap->n,&b->v);CHKERRQ(ierr);
3141ad16ce7aSStefano Zampini     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*B->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
31422205254eSKarl Rupp 
31439e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
3144273d9f13SBarry Smith   } else { /* user-allocated storage */
31459e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
3146273d9f13SBarry Smith     b->v          = data;
3147273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
3148273d9f13SBarry Smith   }
31490450473dSBarry Smith   B->assembled = PETSC_TRUE;
3150273d9f13SBarry Smith   PetscFunctionReturn(0);
3151273d9f13SBarry Smith }
3152273d9f13SBarry Smith 
315365b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3154cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
31558baccfbdSHong Zhang {
3156d77f618aSHong Zhang   Mat               mat_elemental;
3157d77f618aSHong Zhang   PetscErrorCode    ierr;
31581683a169SBarry Smith   const PetscScalar *array;
31591683a169SBarry Smith   PetscScalar       *v_colwise;
3160d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
3161d77f618aSHong Zhang 
31628baccfbdSHong Zhang   PetscFunctionBegin;
3163d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
31641683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&array);CHKERRQ(ierr);
3165d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3166d77f618aSHong Zhang   k = 0;
3167d77f618aSHong Zhang   for (j=0; j<N; j++) {
3168d77f618aSHong Zhang     cols[j] = j;
3169d77f618aSHong Zhang     for (i=0; i<M; i++) {
3170d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
3171d77f618aSHong Zhang     }
3172d77f618aSHong Zhang   }
3173d77f618aSHong Zhang   for (i=0; i<M; i++) {
3174d77f618aSHong Zhang     rows[i] = i;
3175d77f618aSHong Zhang   }
31761683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&array);CHKERRQ(ierr);
3177d77f618aSHong Zhang 
3178d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
3179d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
3180d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
3181d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
3182d77f618aSHong Zhang 
3183d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
3184d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
3185d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3186d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
3187d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
3188d77f618aSHong Zhang 
3189511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
319028be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
3191d77f618aSHong Zhang   } else {
3192d77f618aSHong Zhang     *newmat = mat_elemental;
3193d77f618aSHong Zhang   }
31948baccfbdSHong Zhang   PetscFunctionReturn(0);
31958baccfbdSHong Zhang }
319665b80a83SHong Zhang #endif
31978baccfbdSHong Zhang 
319817359960SJose E. Roman PetscErrorCode  MatDenseSetLDA_SeqDense(Mat B,PetscInt lda)
31991b807ce4Svictorle {
32001b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
32017422da62SJose E. Roman   PetscBool    data;
320221a2c019SBarry Smith 
32031b807ce4Svictorle   PetscFunctionBegin;
32047422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
32052c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!b->user_alloc && data && b->lda!=lda,PETSC_COMM_SELF,PETSC_ERR_ORDER,"LDA cannot be changed after allocation of internal storage");
32062c71b3e2SJacob Faibussowitsch   PetscCheckFalse(lda < B->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"LDA %" PetscInt_FMT " must be at least matrix dimension %" PetscInt_FMT,lda,B->rmap->n);
32071b807ce4Svictorle   b->lda = lda;
32081b807ce4Svictorle   PetscFunctionReturn(0);
32091b807ce4Svictorle }
32101b807ce4Svictorle 
3211d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
3212d528f656SJakub Kruzik {
3213d528f656SJakub Kruzik   PetscErrorCode ierr;
3214d528f656SJakub Kruzik   PetscMPIInt    size;
3215d528f656SJakub Kruzik 
3216d528f656SJakub Kruzik   PetscFunctionBegin;
3217ffc4695bSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr);
3218d528f656SJakub Kruzik   if (size == 1) {
3219d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
3220d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
3221d528f656SJakub Kruzik     } else {
3222d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
3223d528f656SJakub Kruzik     }
3224d528f656SJakub Kruzik   } else {
3225d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
3226d528f656SJakub Kruzik   }
3227d528f656SJakub Kruzik   PetscFunctionReturn(0);
3228d528f656SJakub Kruzik }
3229d528f656SJakub Kruzik 
32306947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
32316947451fSStefano Zampini {
32326947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32336947451fSStefano Zampini   PetscErrorCode ierr;
32346947451fSStefano Zampini 
32356947451fSStefano Zampini   PetscFunctionBegin;
32362c71b3e2SJacob Faibussowitsch   PetscCheckFalse(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
32372c71b3e2SJacob Faibussowitsch   PetscCheckFalse(a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32386947451fSStefano Zampini   if (!a->cvec) {
32396947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
3240616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
32416947451fSStefano Zampini   }
32426947451fSStefano Zampini   a->vecinuse = col + 1;
32436947451fSStefano Zampini   ierr = MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
32446947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
32456947451fSStefano Zampini   *v   = a->cvec;
32466947451fSStefano Zampini   PetscFunctionReturn(0);
32476947451fSStefano Zampini }
32486947451fSStefano Zampini 
32496947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
32506947451fSStefano Zampini {
32516947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32526947451fSStefano Zampini   PetscErrorCode ierr;
32536947451fSStefano Zampini 
32546947451fSStefano Zampini   PetscFunctionBegin;
32552c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
32562c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
32576947451fSStefano Zampini   a->vecinuse = 0;
32586947451fSStefano Zampini   ierr = MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
32596947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
3260*75f6d85dSStefano Zampini   if (v) *v = NULL;
32616947451fSStefano Zampini   PetscFunctionReturn(0);
32626947451fSStefano Zampini }
32636947451fSStefano Zampini 
32646947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
32656947451fSStefano Zampini {
32666947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32676947451fSStefano Zampini   PetscErrorCode ierr;
32686947451fSStefano Zampini 
32696947451fSStefano Zampini   PetscFunctionBegin;
32702c71b3e2SJacob Faibussowitsch   PetscCheckFalse(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
32712c71b3e2SJacob Faibussowitsch   PetscCheckFalse(a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32726947451fSStefano Zampini   if (!a->cvec) {
32736947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
3274616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
32756947451fSStefano Zampini   }
32766947451fSStefano Zampini   a->vecinuse = col + 1;
32776947451fSStefano Zampini   ierr = MatDenseGetArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
32786947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
32796947451fSStefano Zampini   ierr = VecLockReadPush(a->cvec);CHKERRQ(ierr);
32806947451fSStefano Zampini   *v   = a->cvec;
32816947451fSStefano Zampini   PetscFunctionReturn(0);
32826947451fSStefano Zampini }
32836947451fSStefano Zampini 
32846947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
32856947451fSStefano Zampini {
32866947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32876947451fSStefano Zampini   PetscErrorCode ierr;
32886947451fSStefano Zampini 
32896947451fSStefano Zampini   PetscFunctionBegin;
32902c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
32912c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
32926947451fSStefano Zampini   a->vecinuse = 0;
32936947451fSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
32946947451fSStefano Zampini   ierr = VecLockReadPop(a->cvec);CHKERRQ(ierr);
32956947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
3296*75f6d85dSStefano Zampini   if (v) *v = NULL;
32976947451fSStefano Zampini   PetscFunctionReturn(0);
32986947451fSStefano Zampini }
32996947451fSStefano Zampini 
33006947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
33016947451fSStefano Zampini {
33026947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
33036947451fSStefano Zampini   PetscErrorCode ierr;
33046947451fSStefano Zampini 
33056947451fSStefano Zampini   PetscFunctionBegin;
33062c71b3e2SJacob Faibussowitsch   PetscCheckFalse(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
33072c71b3e2SJacob Faibussowitsch   PetscCheckFalse(a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
33086947451fSStefano Zampini   if (!a->cvec) {
33096947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
3310616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
33116947451fSStefano Zampini   }
33126947451fSStefano Zampini   a->vecinuse = col + 1;
33136947451fSStefano Zampini   ierr = MatDenseGetArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
33146947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
33156947451fSStefano Zampini   *v   = a->cvec;
33166947451fSStefano Zampini   PetscFunctionReturn(0);
33176947451fSStefano Zampini }
33186947451fSStefano Zampini 
33196947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
33206947451fSStefano Zampini {
33216947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
33226947451fSStefano Zampini   PetscErrorCode ierr;
33236947451fSStefano Zampini 
33246947451fSStefano Zampini   PetscFunctionBegin;
33252c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
33262c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
33276947451fSStefano Zampini   a->vecinuse = 0;
33286947451fSStefano Zampini   ierr = MatDenseRestoreArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
33296947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
3330*75f6d85dSStefano Zampini   if (v) *v = NULL;
33316947451fSStefano Zampini   PetscFunctionReturn(0);
33326947451fSStefano Zampini }
33336947451fSStefano Zampini 
33345ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
33355ea7661aSPierre Jolivet {
33365ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
33375ea7661aSPierre Jolivet   PetscErrorCode ierr;
33385ea7661aSPierre Jolivet 
33395ea7661aSPierre Jolivet   PetscFunctionBegin;
33402c71b3e2SJacob Faibussowitsch   PetscCheckFalse(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
33412c71b3e2SJacob Faibussowitsch   PetscCheckFalse(a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
33425ea7661aSPierre Jolivet   if (a->cmat && cend-cbegin != a->cmat->cmap->N) {
33435ea7661aSPierre Jolivet     ierr = MatDestroy(&a->cmat);CHKERRQ(ierr);
33445ea7661aSPierre Jolivet   }
33455ea7661aSPierre Jolivet   if (!a->cmat) {
3346*75f6d85dSStefano Zampini     ierr = MatCreateDense(PetscObjectComm((PetscObject)A),A->rmap->n,PETSC_DECIDE,A->rmap->N,cend-cbegin,a->v+(size_t)cbegin*a->lda,&a->cmat);CHKERRQ(ierr);
3347616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cmat);CHKERRQ(ierr);
33485ea7661aSPierre Jolivet   } else {
3349*75f6d85dSStefano Zampini     ierr = MatDensePlaceArray(a->cmat,a->v+(size_t)cbegin*a->lda);CHKERRQ(ierr);
33505ea7661aSPierre Jolivet   }
3351616b8fbbSStefano Zampini   ierr = MatDenseSetLDA(a->cmat,a->lda);CHKERRQ(ierr);
33525ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
33535ea7661aSPierre Jolivet   *v = a->cmat;
3354*75f6d85dSStefano Zampini #if defined(PETSC_HAVE_CUDA)
3355*75f6d85dSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
3356*75f6d85dSStefano Zampini #endif
33575ea7661aSPierre Jolivet   PetscFunctionReturn(0);
33585ea7661aSPierre Jolivet }
33595ea7661aSPierre Jolivet 
33605ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A,Mat *v)
33615ea7661aSPierre Jolivet {
33625ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
33635ea7661aSPierre Jolivet   PetscErrorCode ierr;
33645ea7661aSPierre Jolivet 
33655ea7661aSPierre Jolivet   PetscFunctionBegin;
33662c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetSubMatrix() first");
33672c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!a->cmat,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column matrix");
33682c71b3e2SJacob Faibussowitsch   PetscCheckFalse(*v != a->cmat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not the matrix obtained from MatDenseGetSubMatrix()");
33695ea7661aSPierre Jolivet   a->matinuse = 0;
33705ea7661aSPierre Jolivet   ierr = MatDenseResetArray(a->cmat);CHKERRQ(ierr);
33715ea7661aSPierre Jolivet   *v   = NULL;
33725ea7661aSPierre Jolivet   PetscFunctionReturn(0);
33735ea7661aSPierre Jolivet }
33745ea7661aSPierre Jolivet 
33750bad9183SKris Buschelman /*MC
3376fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
33770bad9183SKris Buschelman 
33780bad9183SKris Buschelman    Options Database Keys:
33790bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
33800bad9183SKris Buschelman 
33810bad9183SKris Buschelman   Level: beginner
33820bad9183SKris Buschelman 
338389665df3SBarry Smith .seealso: MatCreateSeqDense()
338489665df3SBarry Smith 
33850bad9183SKris Buschelman M*/
3386ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
3387273d9f13SBarry Smith {
3388273d9f13SBarry Smith   Mat_SeqDense   *b;
3389dfbe8321SBarry Smith   PetscErrorCode ierr;
33907c334f02SBarry Smith   PetscMPIInt    size;
3391273d9f13SBarry Smith 
3392273d9f13SBarry Smith   PetscFunctionBegin;
3393ffc4695bSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRMPI(ierr);
33942c71b3e2SJacob Faibussowitsch   PetscCheckFalse(size > 1,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
339555659b69SBarry Smith 
3396b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
3397549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
339844cd7ae7SLois Curfman McInnes   B->data = (void*)b;
339918f449edSLois Curfman McInnes 
3400273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
34014e220ebcSLois Curfman McInnes 
34024905a7bcSToby Isaac   ierr = PetscObjectComposeFunction((PetscObject)B,"MatQRFactor_C",MatQRFactor_SeqDense);CHKERRQ(ierr);
340349a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
3404ad16ce7aSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseSetLDA_C",MatDenseSetLDA_SeqDense);CHKERRQ(ierr);
3405bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
34068572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
3407d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
3408d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
3409d5ea218eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseReplaceArray_C",MatDenseReplaceArray_SeqDense);CHKERRQ(ierr);
34108572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
3411715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
34126947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayWrite_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
34136947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayWrite_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
3414bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
34158baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
34168baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
34178baccfbdSHong Zhang #endif
3418d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
3419d24d4204SJose E. Roman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_scalapack_C",MatConvert_Dense_ScaLAPACK);CHKERRQ(ierr);
3420d24d4204SJose E. Roman #endif
34212bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
34222bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA);CHKERRQ(ierr);
34234222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
34244222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
3425637a0070SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
34262bf066beSStefano Zampini #endif
3427bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
34284222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
34294222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
34304222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
34314222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
343296e6d5c4SRichard Tran Mills 
3433af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
3434af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
34356947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVec_C",MatDenseGetColumnVec_SeqDense);CHKERRQ(ierr);
34366947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVec_C",MatDenseRestoreColumnVec_SeqDense);CHKERRQ(ierr);
34376947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecRead_C",MatDenseGetColumnVecRead_SeqDense);CHKERRQ(ierr);
34386947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecRead_C",MatDenseRestoreColumnVecRead_SeqDense);CHKERRQ(ierr);
34396947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecWrite_C",MatDenseGetColumnVecWrite_SeqDense);CHKERRQ(ierr);
34406947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecWrite_C",MatDenseRestoreColumnVecWrite_SeqDense);CHKERRQ(ierr);
34415ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetSubMatrix_C",MatDenseGetSubMatrix_SeqDense);CHKERRQ(ierr);
34425ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreSubMatrix_C",MatDenseRestoreSubMatrix_SeqDense);CHKERRQ(ierr);
344317667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
34443a40ed3dSBarry Smith   PetscFunctionReturn(0);
3445289bc588SBarry Smith }
344686aefd0dSHong Zhang 
344786aefd0dSHong Zhang /*@C
3448af53bab2SHong 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.
344986aefd0dSHong Zhang 
345086aefd0dSHong Zhang    Not Collective
345186aefd0dSHong Zhang 
34525ea7661aSPierre Jolivet    Input Parameters:
345386aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
345486aefd0dSHong Zhang -  col - column index
345586aefd0dSHong Zhang 
345686aefd0dSHong Zhang    Output Parameter:
345786aefd0dSHong Zhang .  vals - pointer to the data
345886aefd0dSHong Zhang 
345986aefd0dSHong Zhang    Level: intermediate
346086aefd0dSHong Zhang 
346186aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
346286aefd0dSHong Zhang @*/
346386aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
346486aefd0dSHong Zhang {
346586aefd0dSHong Zhang   PetscErrorCode ierr;
346686aefd0dSHong Zhang 
346786aefd0dSHong Zhang   PetscFunctionBegin;
3468d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3469d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3470d5ea218eSStefano Zampini   PetscValidPointer(vals,3);
347186aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
347286aefd0dSHong Zhang   PetscFunctionReturn(0);
347386aefd0dSHong Zhang }
347486aefd0dSHong Zhang 
347586aefd0dSHong Zhang /*@C
347686aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
347786aefd0dSHong Zhang 
347886aefd0dSHong Zhang    Not Collective
347986aefd0dSHong Zhang 
348086aefd0dSHong Zhang    Input Parameter:
348186aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
348286aefd0dSHong Zhang 
348386aefd0dSHong Zhang    Output Parameter:
348486aefd0dSHong Zhang .  vals - pointer to the data
348586aefd0dSHong Zhang 
348686aefd0dSHong Zhang    Level: intermediate
348786aefd0dSHong Zhang 
348886aefd0dSHong Zhang .seealso: MatDenseGetColumn()
348986aefd0dSHong Zhang @*/
349086aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
349186aefd0dSHong Zhang {
349286aefd0dSHong Zhang   PetscErrorCode ierr;
349386aefd0dSHong Zhang 
349486aefd0dSHong Zhang   PetscFunctionBegin;
3495d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3496d5ea218eSStefano Zampini   PetscValidPointer(vals,2);
349786aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
349886aefd0dSHong Zhang   PetscFunctionReturn(0);
349986aefd0dSHong Zhang }
35006947451fSStefano Zampini 
35010f74d2c1SSatish Balay /*@
35026947451fSStefano Zampini    MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec.
35036947451fSStefano Zampini 
35046947451fSStefano Zampini    Collective
35056947451fSStefano Zampini 
35065ea7661aSPierre Jolivet    Input Parameters:
35076947451fSStefano Zampini +  mat - the Mat object
35086947451fSStefano Zampini -  col - the column index
35096947451fSStefano Zampini 
35106947451fSStefano Zampini    Output Parameter:
35116947451fSStefano Zampini .  v - the vector
35126947451fSStefano Zampini 
35136947451fSStefano Zampini    Notes:
35146947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed.
35156947451fSStefano Zampini      Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access.
35166947451fSStefano Zampini 
35176947451fSStefano Zampini    Level: intermediate
35186947451fSStefano Zampini 
35196947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
35206947451fSStefano Zampini @*/
35216947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec(Mat A,PetscInt col,Vec *v)
35226947451fSStefano Zampini {
35236947451fSStefano Zampini   PetscErrorCode ierr;
35246947451fSStefano Zampini 
35256947451fSStefano Zampini   PetscFunctionBegin;
35266947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35276947451fSStefano Zampini   PetscValidType(A,1);
35286947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35296947451fSStefano Zampini   PetscValidPointer(v,3);
35302c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35312c71b3e2SJacob Faibussowitsch   PetscCheckFalse(col < 0 || col > A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
35326947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
35336947451fSStefano Zampini   PetscFunctionReturn(0);
35346947451fSStefano Zampini }
35356947451fSStefano Zampini 
35360f74d2c1SSatish Balay /*@
35376947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
35386947451fSStefano Zampini 
35396947451fSStefano Zampini    Collective
35406947451fSStefano Zampini 
35415ea7661aSPierre Jolivet    Input Parameters:
35426947451fSStefano Zampini +  mat - the Mat object
35436947451fSStefano Zampini .  col - the column index
35446947451fSStefano Zampini -  v - the Vec object
35456947451fSStefano Zampini 
35466947451fSStefano Zampini    Level: intermediate
35476947451fSStefano Zampini 
35486947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
35496947451fSStefano Zampini @*/
35506947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec *v)
35516947451fSStefano Zampini {
35526947451fSStefano Zampini   PetscErrorCode ierr;
35536947451fSStefano Zampini 
35546947451fSStefano Zampini   PetscFunctionBegin;
35556947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35566947451fSStefano Zampini   PetscValidType(A,1);
35576947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35582c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35592c71b3e2SJacob Faibussowitsch   PetscCheckFalse(col < 0 || col > A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
35606947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
35616947451fSStefano Zampini   PetscFunctionReturn(0);
35626947451fSStefano Zampini }
35636947451fSStefano Zampini 
35640f74d2c1SSatish Balay /*@
35656947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
35666947451fSStefano Zampini 
35676947451fSStefano Zampini    Collective
35686947451fSStefano Zampini 
35695ea7661aSPierre Jolivet    Input Parameters:
35706947451fSStefano Zampini +  mat - the Mat object
35716947451fSStefano Zampini -  col - the column index
35726947451fSStefano Zampini 
35736947451fSStefano Zampini    Output Parameter:
35746947451fSStefano Zampini .  v - the vector
35756947451fSStefano Zampini 
35766947451fSStefano Zampini    Notes:
35776947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
35786947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
35796947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
35806947451fSStefano Zampini 
35816947451fSStefano Zampini    Level: intermediate
35826947451fSStefano Zampini 
35836947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
35846947451fSStefano Zampini @*/
35856947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec *v)
35866947451fSStefano Zampini {
35876947451fSStefano Zampini   PetscErrorCode ierr;
35886947451fSStefano Zampini 
35896947451fSStefano Zampini   PetscFunctionBegin;
35906947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35916947451fSStefano Zampini   PetscValidType(A,1);
35926947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35936947451fSStefano Zampini   PetscValidPointer(v,3);
35942c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35952c71b3e2SJacob Faibussowitsch   PetscCheckFalse(col < 0 || col > A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
35966947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
35976947451fSStefano Zampini   PetscFunctionReturn(0);
35986947451fSStefano Zampini }
35996947451fSStefano Zampini 
36000f74d2c1SSatish Balay /*@
36016947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
36026947451fSStefano Zampini 
36036947451fSStefano Zampini    Collective
36046947451fSStefano Zampini 
36055ea7661aSPierre Jolivet    Input Parameters:
36066947451fSStefano Zampini +  mat - the Mat object
36076947451fSStefano Zampini .  col - the column index
36086947451fSStefano Zampini -  v - the Vec object
36096947451fSStefano Zampini 
36106947451fSStefano Zampini    Level: intermediate
36116947451fSStefano Zampini 
36126947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecWrite()
36136947451fSStefano Zampini @*/
36146947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec *v)
36156947451fSStefano Zampini {
36166947451fSStefano Zampini   PetscErrorCode ierr;
36176947451fSStefano Zampini 
36186947451fSStefano Zampini   PetscFunctionBegin;
36196947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36206947451fSStefano Zampini   PetscValidType(A,1);
36216947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
36222c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
36232c71b3e2SJacob Faibussowitsch   PetscCheckFalse(col < 0 || col > A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
36246947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
36256947451fSStefano Zampini   PetscFunctionReturn(0);
36266947451fSStefano Zampini }
36276947451fSStefano Zampini 
36280f74d2c1SSatish Balay /*@
36296947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
36306947451fSStefano Zampini 
36316947451fSStefano Zampini    Collective
36326947451fSStefano Zampini 
36335ea7661aSPierre Jolivet    Input Parameters:
36346947451fSStefano Zampini +  mat - the Mat object
36356947451fSStefano Zampini -  col - the column index
36366947451fSStefano Zampini 
36376947451fSStefano Zampini    Output Parameter:
36386947451fSStefano Zampini .  v - the vector
36396947451fSStefano Zampini 
36406947451fSStefano Zampini    Notes:
36416947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
36426947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
36436947451fSStefano Zampini 
36446947451fSStefano Zampini    Level: intermediate
36456947451fSStefano Zampini 
36466947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
36476947451fSStefano Zampini @*/
36486947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec *v)
36496947451fSStefano Zampini {
36506947451fSStefano Zampini   PetscErrorCode ierr;
36516947451fSStefano Zampini 
36526947451fSStefano Zampini   PetscFunctionBegin;
36536947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36546947451fSStefano Zampini   PetscValidType(A,1);
36556947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
36566947451fSStefano Zampini   PetscValidPointer(v,3);
36572c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
36582c71b3e2SJacob Faibussowitsch   PetscCheckFalse(col < 0 || col > A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
36596947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
36606947451fSStefano Zampini   PetscFunctionReturn(0);
36616947451fSStefano Zampini }
36626947451fSStefano Zampini 
36630f74d2c1SSatish Balay /*@
36646947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
36656947451fSStefano Zampini 
36666947451fSStefano Zampini    Collective
36676947451fSStefano Zampini 
36685ea7661aSPierre Jolivet    Input Parameters:
36696947451fSStefano Zampini +  mat - the Mat object
36706947451fSStefano Zampini .  col - the column index
36716947451fSStefano Zampini -  v - the Vec object
36726947451fSStefano Zampini 
36736947451fSStefano Zampini    Level: intermediate
36746947451fSStefano Zampini 
36756947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead()
36766947451fSStefano Zampini @*/
36776947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec *v)
36786947451fSStefano Zampini {
36796947451fSStefano Zampini   PetscErrorCode ierr;
36806947451fSStefano Zampini 
36816947451fSStefano Zampini   PetscFunctionBegin;
36826947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36836947451fSStefano Zampini   PetscValidType(A,1);
36846947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
36852c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
36862c71b3e2SJacob Faibussowitsch   PetscCheckFalse(col < 0 || col > A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
36876947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
36886947451fSStefano Zampini   PetscFunctionReturn(0);
36896947451fSStefano Zampini }
36905ea7661aSPierre Jolivet 
36910f74d2c1SSatish Balay /*@
36925ea7661aSPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of columns of a dense matrix, represented as a Mat.
36935ea7661aSPierre Jolivet 
36945ea7661aSPierre Jolivet    Collective
36955ea7661aSPierre Jolivet 
36965ea7661aSPierre Jolivet    Input Parameters:
36975ea7661aSPierre Jolivet +  mat - the Mat object
36985ea7661aSPierre Jolivet .  cbegin - the first index in the block
36995ea7661aSPierre Jolivet -  cend - the last index in the block
37005ea7661aSPierre Jolivet 
37015ea7661aSPierre Jolivet    Output Parameter:
37025ea7661aSPierre Jolivet .  v - the matrix
37035ea7661aSPierre Jolivet 
37045ea7661aSPierre Jolivet    Notes:
37055ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
37065ea7661aSPierre Jolivet 
37075ea7661aSPierre Jolivet    Level: intermediate
37085ea7661aSPierre Jolivet 
37095ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseRestoreSubMatrix()
37105ea7661aSPierre Jolivet @*/
37115ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
37125ea7661aSPierre Jolivet {
37135ea7661aSPierre Jolivet   PetscErrorCode ierr;
37145ea7661aSPierre Jolivet 
37155ea7661aSPierre Jolivet   PetscFunctionBegin;
37165ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
37175ea7661aSPierre Jolivet   PetscValidType(A,1);
37185ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cbegin,2);
37195ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cend,3);
37205ea7661aSPierre Jolivet   PetscValidPointer(v,4);
37212c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
37222c71b3e2SJacob Faibussowitsch   PetscCheckFalse(cbegin < 0 || cbegin > A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid cbegin %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",cbegin,A->cmap->N);
37232c71b3e2SJacob Faibussowitsch   PetscCheckFalse(cend < cbegin || cend > A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid cend %" PetscInt_FMT ", should be in [%" PetscInt_FMT ",%" PetscInt_FMT ")",cend,cbegin,A->cmap->N);
37245ea7661aSPierre Jolivet   ierr = PetscUseMethod(A,"MatDenseGetSubMatrix_C",(Mat,PetscInt,PetscInt,Mat*),(A,cbegin,cend,v));CHKERRQ(ierr);
37255ea7661aSPierre Jolivet   PetscFunctionReturn(0);
37265ea7661aSPierre Jolivet }
37275ea7661aSPierre Jolivet 
37280f74d2c1SSatish Balay /*@
37295ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
37305ea7661aSPierre Jolivet 
37315ea7661aSPierre Jolivet    Collective
37325ea7661aSPierre Jolivet 
37335ea7661aSPierre Jolivet    Input Parameters:
37345ea7661aSPierre Jolivet +  mat - the Mat object
37355ea7661aSPierre Jolivet -  v - the Mat object
37365ea7661aSPierre Jolivet 
37375ea7661aSPierre Jolivet    Level: intermediate
37385ea7661aSPierre Jolivet 
37395ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseGetSubMatrix()
37405ea7661aSPierre Jolivet @*/
37415ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix(Mat A,Mat *v)
37425ea7661aSPierre Jolivet {
37435ea7661aSPierre Jolivet   PetscErrorCode ierr;
37445ea7661aSPierre Jolivet 
37455ea7661aSPierre Jolivet   PetscFunctionBegin;
37465ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
37475ea7661aSPierre Jolivet   PetscValidType(A,1);
37485ea7661aSPierre Jolivet   PetscValidPointer(v,2);
37495ea7661aSPierre Jolivet   ierr = PetscUseMethod(A,"MatDenseRestoreSubMatrix_C",(Mat,Mat*),(A,v));CHKERRQ(ierr);
37505ea7661aSPierre Jolivet   PetscFunctionReturn(0);
37515ea7661aSPierre Jolivet }
3752