xref: /petsc/src/mat/impls/dense/seq/dense.c (revision a76f77c3ed94e2917eaaee4018985d7f2a196fbc)
1be1d678aSKris Buschelman 
267e560aaSBarry Smith /*
367e560aaSBarry Smith      Defines the basic matrix operations for sequential dense.
467e560aaSBarry Smith */
5289bc588SBarry Smith 
6dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/
7c6db04a5SJed Brown #include <petscblaslapack.h>
8289bc588SBarry Smith 
96a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h>
10b2573a8aSBarry Smith 
11ca15aa20SStefano Zampini PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian)
128c178816SStefano Zampini {
138c178816SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
148c178816SStefano Zampini   PetscInt       j, k, n = A->rmap->n;
15ca15aa20SStefano Zampini   PetscScalar    *v;
16ca15aa20SStefano Zampini   PetscErrorCode ierr;
178c178816SStefano Zampini 
188c178816SStefano Zampini   PetscFunctionBegin;
198c178816SStefano Zampini   if (A->rmap->n != A->cmap->n) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot symmetrize a rectangular matrix");
20ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
218c178816SStefano Zampini   if (!hermitian) {
228c178816SStefano Zampini     for (k=0;k<n;k++) {
238c178816SStefano Zampini       for (j=k;j<n;j++) {
24ca15aa20SStefano Zampini         v[j*mat->lda + k] = v[k*mat->lda + j];
258c178816SStefano Zampini       }
268c178816SStefano Zampini     }
278c178816SStefano Zampini   } else {
288c178816SStefano Zampini     for (k=0;k<n;k++) {
298c178816SStefano Zampini       for (j=k;j<n;j++) {
30ca15aa20SStefano Zampini         v[j*mat->lda + k] = PetscConj(v[k*mat->lda + j]);
318c178816SStefano Zampini       }
328c178816SStefano Zampini     }
338c178816SStefano Zampini   }
34ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
358c178816SStefano Zampini   PetscFunctionReturn(0);
368c178816SStefano Zampini }
378c178816SStefano Zampini 
3805709791SSatish Balay PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A)
398c178816SStefano Zampini {
408c178816SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
418c178816SStefano Zampini   PetscErrorCode ierr;
428c178816SStefano Zampini   PetscBLASInt   info,n;
438c178816SStefano Zampini 
448c178816SStefano Zampini   PetscFunctionBegin;
458c178816SStefano Zampini   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
468c178816SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
478c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
488c178816SStefano Zampini     if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
498c178816SStefano Zampini     if (!mat->fwork) {
508c178816SStefano Zampini       mat->lfwork = n;
518c178816SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
528c178816SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
538c178816SStefano Zampini     }
5400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
558c178816SStefano Zampini     PetscStackCallBLAS("LAPACKgetri",LAPACKgetri_(&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
5600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
57ca15aa20SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
588c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
598c178816SStefano Zampini     if (A->spd) {
6000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
618c178816SStefano Zampini       PetscStackCallBLAS("LAPACKpotri",LAPACKpotri_("L",&n,mat->v,&mat->lda,&info));
6200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
638c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
648c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
658c178816SStefano Zampini     } else if (A->hermitian) {
668c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
678c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
6800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
698c178816SStefano Zampini       PetscStackCallBLAS("LAPACKhetri",LAPACKhetri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
7000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
718c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr);
728c178816SStefano Zampini #endif
738c178816SStefano Zampini     } else { /* symmetric case */
748c178816SStefano Zampini       if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
758c178816SStefano Zampini       if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
7600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
778c178816SStefano Zampini       PetscStackCallBLAS("LAPACKsytri",LAPACKsytri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
7800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
798c178816SStefano Zampini       ierr = MatSeqDenseSymmetrize_Private(A,PETSC_FALSE);CHKERRQ(ierr);
808c178816SStefano Zampini     }
818c178816SStefano Zampini     if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad Inversion: zero pivot in row %D",(PetscInt)info-1);
82ca15aa20SStefano Zampini     ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
838c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
848c178816SStefano Zampini 
858c178816SStefano Zampini   A->ops->solve             = NULL;
868c178816SStefano Zampini   A->ops->matsolve          = NULL;
878c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
888c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
898c178816SStefano Zampini   A->ops->solveadd          = NULL;
908c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
918c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
928c178816SStefano Zampini   ierr                      = PetscFree(A->solvertype);CHKERRQ(ierr);
938c178816SStefano Zampini   PetscFunctionReturn(0);
948c178816SStefano Zampini }
958c178816SStefano Zampini 
963f49a652SStefano Zampini PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
973f49a652SStefano Zampini {
983f49a652SStefano Zampini   PetscErrorCode    ierr;
993f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1003f49a652SStefano Zampini   PetscInt          m  = l->lda, n = A->cmap->n,r = A->rmap->n, i,j;
101ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
1023f49a652SStefano Zampini   const PetscScalar *xx;
1033f49a652SStefano Zampini 
1043f49a652SStefano Zampini   PetscFunctionBegin;
10576bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1063f49a652SStefano Zampini     for (i=0; i<N; i++) {
1073f49a652SStefano Zampini       if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1083f49a652SStefano Zampini       if (rows[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D requested to be zeroed greater than or equal number of rows %D",rows[i],A->rmap->n);
1093f49a652SStefano Zampini       if (rows[i] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Col %D requested to be zeroed greater than or equal number of cols %D",rows[i],A->cmap->n);
1103f49a652SStefano Zampini     }
11176bd3646SJed Brown   }
112ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1133f49a652SStefano Zampini 
1143f49a652SStefano Zampini   /* fix right hand side if needed */
1153f49a652SStefano Zampini   if (x && b) {
1166c4d906cSStefano Zampini     Vec xt;
1176c4d906cSStefano Zampini 
1186c4d906cSStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1196c4d906cSStefano Zampini     ierr = VecDuplicate(x,&xt);CHKERRQ(ierr);
1206c4d906cSStefano Zampini     ierr = VecCopy(x,xt);CHKERRQ(ierr);
1216c4d906cSStefano Zampini     ierr = VecScale(xt,-1.0);CHKERRQ(ierr);
1226c4d906cSStefano Zampini     ierr = MatMultAdd(A,xt,b,b);CHKERRQ(ierr);
1236c4d906cSStefano Zampini     ierr = VecDestroy(&xt);CHKERRQ(ierr);
1243f49a652SStefano Zampini     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
1253f49a652SStefano Zampini     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
1263f49a652SStefano Zampini     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
1273f49a652SStefano Zampini     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
1283f49a652SStefano Zampini     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
1293f49a652SStefano Zampini   }
1303f49a652SStefano Zampini 
131ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1323f49a652SStefano Zampini   for (i=0; i<N; i++) {
133ca15aa20SStefano Zampini     slot = v + rows[i]*m;
134580bdb30SBarry Smith     ierr = PetscArrayzero(slot,r);CHKERRQ(ierr);
1353f49a652SStefano Zampini   }
1363f49a652SStefano Zampini   for (i=0; i<N; i++) {
137ca15aa20SStefano Zampini     slot = v + rows[i];
1383f49a652SStefano Zampini     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
1393f49a652SStefano Zampini   }
1403f49a652SStefano Zampini   if (diag != 0.0) {
1413f49a652SStefano Zampini     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1423f49a652SStefano Zampini     for (i=0; i<N; i++) {
143ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1443f49a652SStefano Zampini       *slot = diag;
1453f49a652SStefano Zampini     }
1463f49a652SStefano Zampini   }
147ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
1483f49a652SStefano Zampini   PetscFunctionReturn(0);
1493f49a652SStefano Zampini }
1503f49a652SStefano Zampini 
151abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C)
152abc3b08eSStefano Zampini {
153abc3b08eSStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)(C->data);
154abc3b08eSStefano Zampini   PetscErrorCode ierr;
155abc3b08eSStefano Zampini 
156abc3b08eSStefano Zampini   PetscFunctionBegin;
157ca15aa20SStefano Zampini   if (c->ptapwork) {
158ca15aa20SStefano Zampini     ierr = (*C->ops->matmultnumeric)(A,P,c->ptapwork);CHKERRQ(ierr);
159ca15aa20SStefano Zampini     ierr = (*C->ops->transposematmultnumeric)(P,c->ptapwork,C);CHKERRQ(ierr);
1604222ddf1SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"Must call MatPtAPSymbolic_SeqDense_SeqDense() first");
161abc3b08eSStefano Zampini   PetscFunctionReturn(0);
162abc3b08eSStefano Zampini }
163abc3b08eSStefano Zampini 
1644222ddf1SHong Zhang PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat C)
165abc3b08eSStefano Zampini {
166abc3b08eSStefano Zampini   Mat_SeqDense   *c;
1677a3c3d58SStefano Zampini   PetscBool      cisdense;
168abc3b08eSStefano Zampini   PetscErrorCode ierr;
169abc3b08eSStefano Zampini 
170abc3b08eSStefano Zampini   PetscFunctionBegin;
1714222ddf1SHong Zhang   ierr = MatSetSizes(C,P->cmap->n,P->cmap->n,P->cmap->N,P->cmap->N);CHKERRQ(ierr);
1727a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
1737a3c3d58SStefano Zampini   if (!cisdense) {
1747a3c3d58SStefano Zampini     PetscBool flg;
1757a3c3d58SStefano Zampini 
1767a3c3d58SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)P,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
1774222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
1787a3c3d58SStefano Zampini   }
1797a3c3d58SStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
1804222ddf1SHong Zhang   c    = (Mat_SeqDense*)C->data;
181ca15aa20SStefano Zampini   ierr = MatCreate(PetscObjectComm((PetscObject)A),&c->ptapwork);CHKERRQ(ierr);
182ca15aa20SStefano Zampini   ierr = MatSetSizes(c->ptapwork,A->rmap->n,P->cmap->n,A->rmap->N,P->cmap->N);CHKERRQ(ierr);
1837a3c3d58SStefano Zampini   ierr = MatSetType(c->ptapwork,((PetscObject)C)->type_name);CHKERRQ(ierr);
1847a3c3d58SStefano Zampini   ierr = MatSetUp(c->ptapwork);CHKERRQ(ierr);
185abc3b08eSStefano Zampini   PetscFunctionReturn(0);
186abc3b08eSStefano Zampini }
187abc3b08eSStefano Zampini 
188cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
189b49cda9fSStefano Zampini {
190a13144ffSStefano Zampini   Mat             B = NULL;
191b49cda9fSStefano Zampini   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
192b49cda9fSStefano Zampini   Mat_SeqDense    *b;
193b49cda9fSStefano Zampini   PetscErrorCode  ierr;
194b49cda9fSStefano Zampini   PetscInt        *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i;
1952e5835c6SStefano Zampini   const MatScalar *av;
196a13144ffSStefano Zampini   PetscBool       isseqdense;
197b49cda9fSStefano Zampini 
198b49cda9fSStefano Zampini   PetscFunctionBegin;
199a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
200a13144ffSStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense);CHKERRQ(ierr);
201a32993e3SJed Brown     if (!isseqdense) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type_name);
202a13144ffSStefano Zampini   }
203a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
204b49cda9fSStefano Zampini     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
205b49cda9fSStefano Zampini     ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr);
206b49cda9fSStefano Zampini     ierr = MatSetType(B,MATSEQDENSE);CHKERRQ(ierr);
207b49cda9fSStefano Zampini     ierr = MatSeqDenseSetPreallocation(B,NULL);CHKERRQ(ierr);
208b49cda9fSStefano Zampini     b    = (Mat_SeqDense*)(B->data);
209a13144ffSStefano Zampini   } else {
210a13144ffSStefano Zampini     b    = (Mat_SeqDense*)((*newmat)->data);
211580bdb30SBarry Smith     ierr = PetscArrayzero(b->v,m*n);CHKERRQ(ierr);
212a13144ffSStefano Zampini   }
2132e5835c6SStefano Zampini   ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr);
214b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
215b49cda9fSStefano Zampini     PetscInt j;
216b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
217b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
218b49cda9fSStefano Zampini       aj++;
219b49cda9fSStefano Zampini       av++;
220b49cda9fSStefano Zampini     }
221b49cda9fSStefano Zampini     ai++;
222b49cda9fSStefano Zampini   }
2232e5835c6SStefano Zampini   ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr);
224b49cda9fSStefano Zampini 
225511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
226a13144ffSStefano Zampini     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
227a13144ffSStefano Zampini     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22828be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
229b49cda9fSStefano Zampini   } else {
230a13144ffSStefano Zampini     if (B) *newmat = B;
231a13144ffSStefano Zampini     ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
232a13144ffSStefano Zampini     ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
233b49cda9fSStefano Zampini   }
234b49cda9fSStefano Zampini   PetscFunctionReturn(0);
235b49cda9fSStefano Zampini }
236b49cda9fSStefano Zampini 
237cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
2386a63e612SBarry Smith {
2396a63e612SBarry Smith   Mat            B;
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;
247ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
2486a63e612SBarry Smith   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
2496a63e612SBarry Smith   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
2509399e1b8SMatthew G. Knepley   ierr = PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals);CHKERRQ(ierr);
2519399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2529399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) ++nnz[i];
2536a63e612SBarry Smith     aa += a->lda;
2546a63e612SBarry Smith   }
2559399e1b8SMatthew G. Knepley   ierr = MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz);CHKERRQ(ierr);
2569399e1b8SMatthew G. Knepley   aa = a->v;
2579399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2589399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2599399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) {rows[numRows] = i; vals[numRows++] = aa[i];}
2609399e1b8SMatthew G. Knepley     ierr = MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr);
2619399e1b8SMatthew G. Knepley     aa  += a->lda;
2629399e1b8SMatthew G. Knepley   }
2639399e1b8SMatthew G. Knepley   ierr = PetscFree3(rows,nnz,vals);CHKERRQ(ierr);
2646a63e612SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2656a63e612SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2666a63e612SBarry Smith 
267511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
26828be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
2696a63e612SBarry Smith   } else {
2706a63e612SBarry Smith     *newmat = B;
2716a63e612SBarry Smith   }
2726a63e612SBarry Smith   PetscFunctionReturn(0);
2736a63e612SBarry Smith }
2746a63e612SBarry Smith 
275ca15aa20SStefano Zampini PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
2761987afe7SBarry Smith {
2771987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
278ca15aa20SStefano Zampini   const PetscScalar *xv;
279ca15aa20SStefano Zampini   PetscScalar       *yv;
28023fff9afSBarry Smith   PetscBLASInt      N,m,ldax = 0,lday = 0,one = 1;
281efee365bSSatish Balay   PetscErrorCode    ierr;
2823a40ed3dSBarry Smith 
2833a40ed3dSBarry Smith   PetscFunctionBegin;
284ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(X,&xv);CHKERRQ(ierr);
285ca15aa20SStefano Zampini   ierr = MatDenseGetArray(Y,&yv);CHKERRQ(ierr);
286c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n*X->cmap->n,&N);CHKERRQ(ierr);
287c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n,&m);CHKERRQ(ierr);
288c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->lda,&ldax);CHKERRQ(ierr);
289c5df96a5SBarry Smith   ierr = PetscBLASIntCast(y->lda,&lday);CHKERRQ(ierr);
290a5ce6ee0Svictorle   if (ldax>m || lday>m) {
291ca15aa20SStefano Zampini     PetscInt j;
292ca15aa20SStefano Zampini 
293d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
294ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&alpha,xv+j*ldax,&one,yv+j*lday,&one));
295a5ce6ee0Svictorle     }
296a5ce6ee0Svictorle   } else {
297ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&alpha,xv,&one,yv,&one));
298a5ce6ee0Svictorle   }
299ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(X,&xv);CHKERRQ(ierr);
300ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(Y,&yv);CHKERRQ(ierr);
301ca0c957dSBarry Smith   ierr = PetscLogFlops(PetscMax(2.0*N-1,0));CHKERRQ(ierr);
3023a40ed3dSBarry Smith   PetscFunctionReturn(0);
3031987afe7SBarry Smith }
3041987afe7SBarry Smith 
305e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
306289bc588SBarry Smith {
307ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n*A->cmap->n;
3083a40ed3dSBarry Smith 
3093a40ed3dSBarry Smith   PetscFunctionBegin;
3104e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
311ca15aa20SStefano Zampini   info->nz_allocated      = N;
312ca15aa20SStefano Zampini   info->nz_used           = N;
313ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
314ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
3154e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3167adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3174e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3184e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3194e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3203a40ed3dSBarry Smith   PetscFunctionReturn(0);
321289bc588SBarry Smith }
322289bc588SBarry Smith 
323637a0070SStefano Zampini PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
32480cd9d93SLois Curfman McInnes {
325273d9f13SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
326ca15aa20SStefano Zampini   PetscScalar    *v;
327efee365bSSatish Balay   PetscErrorCode ierr;
32823fff9afSBarry Smith   PetscBLASInt   one = 1,j,nz,lda = 0;
32980cd9d93SLois Curfman McInnes 
3303a40ed3dSBarry Smith   PetscFunctionBegin;
331ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
332c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->lda,&lda);CHKERRQ(ierr);
333d0f46423SBarry Smith   if (lda>A->rmap->n) {
334c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n,&nz);CHKERRQ(ierr);
335d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
336ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v+j*lda,&one));
337a5ce6ee0Svictorle     }
338a5ce6ee0Svictorle   } else {
339c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz);CHKERRQ(ierr);
340ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v,&one));
341a5ce6ee0Svictorle   }
342efee365bSSatish Balay   ierr = PetscLogFlops(nz);CHKERRQ(ierr);
343ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
3443a40ed3dSBarry Smith   PetscFunctionReturn(0);
34580cd9d93SLois Curfman McInnes }
34680cd9d93SLois Curfman McInnes 
347e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3481cbb95d3SBarry Smith {
3491cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
350ca15aa20SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
351ca15aa20SStefano Zampini   const PetscScalar *v;
352ca15aa20SStefano Zampini   PetscErrorCode    ierr;
3531cbb95d3SBarry Smith 
3541cbb95d3SBarry Smith   PetscFunctionBegin;
3551cbb95d3SBarry Smith   *fl = PETSC_FALSE;
356d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
357ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
3581cbb95d3SBarry Smith   for (i=0; i<m; i++) {
359ca15aa20SStefano Zampini     for (j=i; j<m; j++) {
360637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) {
361637a0070SStefano Zampini         goto restore;
3621cbb95d3SBarry Smith       }
3631cbb95d3SBarry Smith     }
364637a0070SStefano Zampini   }
3651cbb95d3SBarry Smith   *fl  = PETSC_TRUE;
366637a0070SStefano Zampini restore:
367637a0070SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
368637a0070SStefano Zampini   PetscFunctionReturn(0);
369637a0070SStefano Zampini }
370637a0070SStefano Zampini 
371637a0070SStefano Zampini static PetscErrorCode MatIsSymmetric_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
372637a0070SStefano Zampini {
373637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
374637a0070SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
375637a0070SStefano Zampini   const PetscScalar *v;
376637a0070SStefano Zampini   PetscErrorCode    ierr;
377637a0070SStefano Zampini 
378637a0070SStefano Zampini   PetscFunctionBegin;
379637a0070SStefano Zampini   *fl = PETSC_FALSE;
380637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
381637a0070SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
382637a0070SStefano Zampini   for (i=0; i<m; i++) {
383637a0070SStefano Zampini     for (j=i; j<m; j++) {
384637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - v[j+i*N]) > rtol) {
385637a0070SStefano Zampini         goto restore;
386637a0070SStefano Zampini       }
387637a0070SStefano Zampini     }
388637a0070SStefano Zampini   }
389637a0070SStefano Zampini   *fl  = PETSC_TRUE;
390637a0070SStefano Zampini restore:
391637a0070SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
3921cbb95d3SBarry Smith   PetscFunctionReturn(0);
3931cbb95d3SBarry Smith }
3941cbb95d3SBarry Smith 
395ca15aa20SStefano Zampini PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
396b24902e0SBarry Smith {
397ca15aa20SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
398b24902e0SBarry Smith   PetscErrorCode ierr;
39923fc5dcaSStefano Zampini   PetscInt       lda = (PetscInt)mat->lda,j,m,nlda = lda;
400b24902e0SBarry Smith 
401b24902e0SBarry Smith   PetscFunctionBegin;
402aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr);
403aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr);
40423fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
40523fc5dcaSStefano Zampini     ierr = MatDenseSetLDA(newi,lda);CHKERRQ(ierr);
40623fc5dcaSStefano Zampini   }
4070298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr);
408b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
409ca15aa20SStefano Zampini     const PetscScalar *av;
410ca15aa20SStefano Zampini     PetscScalar       *v;
411ca15aa20SStefano Zampini 
412ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
413ca15aa20SStefano Zampini     ierr = MatDenseGetArray(newi,&v);CHKERRQ(ierr);
41423fc5dcaSStefano Zampini     ierr = MatDenseGetLDA(newi,&nlda);CHKERRQ(ierr);
415d0f46423SBarry Smith     m    = A->rmap->n;
41623fc5dcaSStefano Zampini     if (lda>m || nlda>m) {
417d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
41823fc5dcaSStefano Zampini         ierr = PetscArraycpy(v+j*nlda,av+j*lda,m);CHKERRQ(ierr);
419b24902e0SBarry Smith       }
420b24902e0SBarry Smith     } else {
421ca15aa20SStefano Zampini       ierr = PetscArraycpy(v,av,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
422b24902e0SBarry Smith     }
423ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(newi,&v);CHKERRQ(ierr);
424ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
425b24902e0SBarry Smith   }
426b24902e0SBarry Smith   PetscFunctionReturn(0);
427b24902e0SBarry Smith }
428b24902e0SBarry Smith 
429ca15aa20SStefano Zampini PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
43002cad45dSBarry Smith {
4316849ba73SBarry Smith   PetscErrorCode ierr;
43202cad45dSBarry Smith 
4333a40ed3dSBarry Smith   PetscFunctionBegin;
434ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr);
435d0f46423SBarry Smith   ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4365c9eb25fSBarry Smith   ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
437719d5645SBarry Smith   ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr);
438b24902e0SBarry Smith   PetscFunctionReturn(0);
439b24902e0SBarry Smith }
440b24902e0SBarry Smith 
441e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
442289bc588SBarry Smith {
4434482741eSBarry Smith   MatFactorInfo  info;
444a093e273SMatthew Knepley   PetscErrorCode ierr;
4453a40ed3dSBarry Smith 
4463a40ed3dSBarry Smith   PetscFunctionBegin;
447c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
448f4259b30SLisandro Dalcin   ierr = (*fact->ops->lufactor)(fact,NULL,NULL,&info);CHKERRQ(ierr);
4493a40ed3dSBarry Smith   PetscFunctionReturn(0);
450289bc588SBarry Smith }
4516ee01492SSatish Balay 
452e0877f53SBarry Smith static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy)
453289bc588SBarry Smith {
454c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
4556849ba73SBarry Smith   PetscErrorCode    ierr;
456f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
457f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
458c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
45967e560aaSBarry Smith 
4603a40ed3dSBarry Smith   PetscFunctionBegin;
461c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
462f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4631ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
464580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
465d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_LU) {
46600121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4678b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
46800121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
469e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
470d5f3da31SBarry Smith   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
471a49dc2a2SStefano Zampini     if (A->spd) {
47200121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4738b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
47400121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
475e32f2f54SBarry Smith       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
476a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
477a49dc2a2SStefano Zampini     } else if (A->hermitian) {
47800121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
479a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
48000121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
481a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
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,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
48600121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
487a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
488a49dc2a2SStefano Zampini     }
4892205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
490f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4911ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
492dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
4933a40ed3dSBarry Smith   PetscFunctionReturn(0);
494289bc588SBarry Smith }
4956ee01492SSatish Balay 
496e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X)
49785e2c93fSHong Zhang {
49885e2c93fSHong Zhang   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
49985e2c93fSHong Zhang   PetscErrorCode    ierr;
5001683a169SBarry Smith   const PetscScalar *b;
5011683a169SBarry Smith   PetscScalar       *x;
502efb80c78SLisandro Dalcin   PetscInt          n;
503783b601eSJed Brown   PetscBLASInt      nrhs,info,m;
50485e2c93fSHong Zhang 
50585e2c93fSHong Zhang   PetscFunctionBegin;
506c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
5070298fd71SBarry Smith   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
508c5df96a5SBarry Smith   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
5091683a169SBarry Smith   ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
5108c778c55SBarry Smith   ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr);
51185e2c93fSHong Zhang 
512580bdb30SBarry Smith   ierr = PetscArraycpy(x,b,m*nrhs);CHKERRQ(ierr);
51385e2c93fSHong Zhang 
51485e2c93fSHong Zhang   if (A->factortype == MAT_FACTOR_LU) {
51500121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5168b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
51700121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
51885e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
51985e2c93fSHong Zhang   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
520a49dc2a2SStefano Zampini     if (A->spd) {
52100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5228b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
52300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
52485e2c93fSHong Zhang       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
525a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
526a49dc2a2SStefano Zampini     } else if (A->hermitian) {
52700121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
528a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
52900121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
530a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
531a49dc2a2SStefano Zampini #endif
532a49dc2a2SStefano Zampini     } else { /* symmetric case */
53300121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
534a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
53500121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
536a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
537a49dc2a2SStefano Zampini     }
5382205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
53985e2c93fSHong Zhang 
5401683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
5418c778c55SBarry Smith   ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr);
54285e2c93fSHong Zhang   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
54385e2c93fSHong Zhang   PetscFunctionReturn(0);
54485e2c93fSHong Zhang }
54585e2c93fSHong Zhang 
54600121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
54700121966SStefano Zampini 
548e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
549da3a660dSBarry Smith {
550c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
551dfbe8321SBarry Smith   PetscErrorCode    ierr;
552f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
553f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
554c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
55567e560aaSBarry Smith 
5563a40ed3dSBarry Smith   PetscFunctionBegin;
557c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
558f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5591ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
560580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
5618208b9aeSStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
56200121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5638b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
56400121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
565e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve");
5668208b9aeSStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
567a49dc2a2SStefano Zampini     if (A->spd) {
56800121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
56900121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
57000121966SStefano Zampini #endif
57100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5728b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
57300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
57400121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
57500121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
57600121966SStefano Zampini #endif
577a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
578a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
579a49dc2a2SStefano Zampini     } else if (A->hermitian) {
58000121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
58100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
58200121966SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
58300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
58400121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
585ae7cfcebSSatish Balay #endif
586a49dc2a2SStefano Zampini     } else { /* symmetric case */
58700121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
588a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
58900121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
590a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
591da3a660dSBarry Smith     }
592a49dc2a2SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
593f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5941ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
595dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
5963a40ed3dSBarry Smith   PetscFunctionReturn(0);
597da3a660dSBarry Smith }
5986ee01492SSatish Balay 
599db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
600db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
601db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
602ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
603db4efbfdSBarry Smith {
604db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
605db4efbfdSBarry Smith   PetscErrorCode ierr;
606db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
607db4efbfdSBarry Smith 
608db4efbfdSBarry Smith   PetscFunctionBegin;
609c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
610c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
611db4efbfdSBarry Smith   if (!mat->pivots) {
6128208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
6133bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
614db4efbfdSBarry Smith   }
615db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
6168e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6178b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
6188e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
6198e57ea43SSatish Balay 
620e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
621e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
6228208b9aeSStefano Zampini 
623db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6248208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
625db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
626d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
627db4efbfdSBarry Smith 
628f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
629f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
630f6224b95SHong Zhang 
631dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
632db4efbfdSBarry Smith   PetscFunctionReturn(0);
633db4efbfdSBarry Smith }
634db4efbfdSBarry Smith 
635a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
636ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
637db4efbfdSBarry Smith {
638db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
639db4efbfdSBarry Smith   PetscErrorCode ierr;
640c5df96a5SBarry Smith   PetscBLASInt   info,n;
641db4efbfdSBarry Smith 
642db4efbfdSBarry Smith   PetscFunctionBegin;
643c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
644db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
645a49dc2a2SStefano Zampini   if (A->spd) {
64600121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6478b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
64800121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
649a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
650a49dc2a2SStefano Zampini   } else if (A->hermitian) {
651a49dc2a2SStefano Zampini     if (!mat->pivots) {
652a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
653a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
654a49dc2a2SStefano Zampini     }
655a49dc2a2SStefano Zampini     if (!mat->fwork) {
656a49dc2a2SStefano Zampini       PetscScalar dummy;
657a49dc2a2SStefano Zampini 
658a49dc2a2SStefano Zampini       mat->lfwork = -1;
65900121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
660a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
66100121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
662a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
663a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
664a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
665a49dc2a2SStefano Zampini     }
66600121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
667a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
66800121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
669a49dc2a2SStefano Zampini #endif
670a49dc2a2SStefano Zampini   } else { /* symmetric case */
671a49dc2a2SStefano Zampini     if (!mat->pivots) {
672a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
673a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
674a49dc2a2SStefano Zampini     }
675a49dc2a2SStefano Zampini     if (!mat->fwork) {
676a49dc2a2SStefano Zampini       PetscScalar dummy;
677a49dc2a2SStefano Zampini 
678a49dc2a2SStefano Zampini       mat->lfwork = -1;
67900121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
680a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
68100121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
682a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
683a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
684a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
685a49dc2a2SStefano Zampini     }
68600121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
687a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
68800121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
689a49dc2a2SStefano Zampini   }
690e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
6918208b9aeSStefano Zampini 
692db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6938208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
694db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
695d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
6962205254eSKarl Rupp 
697f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
698f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
699f6224b95SHong Zhang 
700eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
701db4efbfdSBarry Smith   PetscFunctionReturn(0);
702db4efbfdSBarry Smith }
703db4efbfdSBarry Smith 
7040481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
705db4efbfdSBarry Smith {
706db4efbfdSBarry Smith   PetscErrorCode ierr;
707db4efbfdSBarry Smith   MatFactorInfo  info;
708db4efbfdSBarry Smith 
709db4efbfdSBarry Smith   PetscFunctionBegin;
710db4efbfdSBarry Smith   info.fill = 1.0;
7112205254eSKarl Rupp 
712c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
713f4259b30SLisandro Dalcin   ierr = (*fact->ops->choleskyfactor)(fact,NULL,&info);CHKERRQ(ierr);
714db4efbfdSBarry Smith   PetscFunctionReturn(0);
715db4efbfdSBarry Smith }
716db4efbfdSBarry Smith 
717ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
718db4efbfdSBarry Smith {
719db4efbfdSBarry Smith   PetscFunctionBegin;
720c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
7211bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
722719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
723bd443b22SStefano Zampini   fact->ops->solve                 = MatSolve_SeqDense;
724bd443b22SStefano Zampini   fact->ops->matsolve              = MatMatSolve_SeqDense;
725bd443b22SStefano Zampini   fact->ops->solvetranspose        = MatSolveTranspose_SeqDense;
726db4efbfdSBarry Smith   PetscFunctionReturn(0);
727db4efbfdSBarry Smith }
728db4efbfdSBarry Smith 
729ca15aa20SStefano Zampini PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
730db4efbfdSBarry Smith {
731db4efbfdSBarry Smith   PetscFunctionBegin;
732b66fe19dSMatthew G Knepley   fact->preallocated           = PETSC_TRUE;
733c3ef05f6SHong Zhang   fact->assembled              = PETSC_TRUE;
734719d5645SBarry Smith   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
735bd443b22SStefano Zampini   fact->ops->solve             = MatSolve_SeqDense;
736bd443b22SStefano Zampini   fact->ops->matsolve          = MatMatSolve_SeqDense;
737bd443b22SStefano Zampini   fact->ops->solvetranspose    = MatSolveTranspose_SeqDense;
738db4efbfdSBarry Smith   PetscFunctionReturn(0);
739db4efbfdSBarry Smith }
740db4efbfdSBarry Smith 
741ca15aa20SStefano Zampini /* uses LAPACK */
742cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
743db4efbfdSBarry Smith {
744db4efbfdSBarry Smith   PetscErrorCode ierr;
745db4efbfdSBarry Smith 
746db4efbfdSBarry Smith   PetscFunctionBegin;
747ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
748db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
749ca15aa20SStefano Zampini   ierr = MatSetType(*fact,MATDENSE);CHKERRQ(ierr);
7502a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
751db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
7522a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
753db4efbfdSBarry Smith   } else {
754db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
755db4efbfdSBarry Smith   }
756d5f3da31SBarry Smith   (*fact)->factortype = ftype;
75700c67f3bSHong Zhang 
75800c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
75900c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
760db4efbfdSBarry Smith   PetscFunctionReturn(0);
761db4efbfdSBarry Smith }
762db4efbfdSBarry Smith 
763289bc588SBarry Smith /* ------------------------------------------------------------------*/
764e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
765289bc588SBarry Smith {
766c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
767d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
768d9ca1df4SBarry Smith   const PetscScalar *b;
769dfbe8321SBarry Smith   PetscErrorCode    ierr;
770d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
77123fff9afSBarry Smith   PetscBLASInt      o = 1,bm = 0;
772289bc588SBarry Smith 
7733a40ed3dSBarry Smith   PetscFunctionBegin;
774ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
775c70f7ee4SJunchao Zhang   if (A->offloadmask == PETSC_OFFLOAD_GPU) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
776ca15aa20SStefano Zampini #endif
777422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
778c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
779289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
7803bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
7812dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
782289bc588SBarry Smith   }
7831ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
784d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
785b965ef7fSBarry Smith   its  = its*lits;
786e32f2f54SBarry Smith   if (its <= 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits);
787289bc588SBarry Smith   while (its--) {
788fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
789289bc588SBarry Smith       for (i=0; i<m; i++) {
7903bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
79155a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
792289bc588SBarry Smith       }
793289bc588SBarry Smith     }
794fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
795289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
7963bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
79755a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
798289bc588SBarry Smith       }
799289bc588SBarry Smith     }
800289bc588SBarry Smith   }
801d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
8021ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
8033a40ed3dSBarry Smith   PetscFunctionReturn(0);
804289bc588SBarry Smith }
805289bc588SBarry Smith 
806289bc588SBarry Smith /* -----------------------------------------------------------------*/
807ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
808289bc588SBarry Smith {
809c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
810d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
811d9ca1df4SBarry Smith   PetscScalar       *y;
812dfbe8321SBarry Smith   PetscErrorCode    ierr;
8130805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
814ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
8153a40ed3dSBarry Smith 
8163a40ed3dSBarry Smith   PetscFunctionBegin;
817c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
818c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
819d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8202bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
8215ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8225ac36cfcSBarry Smith     PetscBLASInt i;
8235ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
8245ac36cfcSBarry Smith   } else {
8258b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
8265ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
8275ac36cfcSBarry Smith   }
828d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8292bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
8303a40ed3dSBarry Smith   PetscFunctionReturn(0);
831289bc588SBarry Smith }
832800995b7SMatthew Knepley 
833ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
834289bc588SBarry Smith {
835c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
836d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
837dfbe8321SBarry Smith   PetscErrorCode    ierr;
8380805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
839d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
8403a40ed3dSBarry Smith 
8413a40ed3dSBarry Smith   PetscFunctionBegin;
842c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
843c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
844d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8452bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
8465ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8475ac36cfcSBarry Smith     PetscBLASInt i;
8485ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
8495ac36cfcSBarry Smith   } else {
8508b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
8515ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
8525ac36cfcSBarry Smith   }
853d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8542bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
8553a40ed3dSBarry Smith   PetscFunctionReturn(0);
856289bc588SBarry Smith }
8576ee01492SSatish Balay 
858ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
859289bc588SBarry Smith {
860c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
861d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
862d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
863dfbe8321SBarry Smith   PetscErrorCode    ierr;
8640805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
8653a40ed3dSBarry Smith 
8663a40ed3dSBarry Smith   PetscFunctionBegin;
867c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
868c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
86917b127eeSStefano Zampini   ierr = VecCopy(zz,yy);CHKERRQ(ierr);
870d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
871d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8721ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8738b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
874d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8751ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
876dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8773a40ed3dSBarry Smith   PetscFunctionReturn(0);
878289bc588SBarry Smith }
8796ee01492SSatish Balay 
880ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
881289bc588SBarry Smith {
882c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
883d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
884d9ca1df4SBarry Smith   PetscScalar       *y;
885dfbe8321SBarry Smith   PetscErrorCode    ierr;
8860805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
88787828ca2SBarry Smith   PetscScalar       _DOne=1.0;
8883a40ed3dSBarry Smith 
8893a40ed3dSBarry Smith   PetscFunctionBegin;
890c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
891c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
89217b127eeSStefano Zampini   ierr = VecCopy(zz,yy);CHKERRQ(ierr);
893d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
894d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8951ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8968b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
897d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8981ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
899dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
9003a40ed3dSBarry Smith   PetscFunctionReturn(0);
901289bc588SBarry Smith }
902289bc588SBarry Smith 
903289bc588SBarry Smith /* -----------------------------------------------------------------*/
904e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
905289bc588SBarry Smith {
906c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
9076849ba73SBarry Smith   PetscErrorCode ierr;
90813f74950SBarry Smith   PetscInt       i;
90967e560aaSBarry Smith 
9103a40ed3dSBarry Smith   PetscFunctionBegin;
911d0f46423SBarry Smith   *ncols = A->cmap->n;
912289bc588SBarry Smith   if (cols) {
913854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
914d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
915289bc588SBarry Smith   }
916289bc588SBarry Smith   if (vals) {
917ca15aa20SStefano Zampini     const PetscScalar *v;
918ca15aa20SStefano Zampini 
919ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
920854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
921ca15aa20SStefano Zampini     v   += row;
922d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
923ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
924289bc588SBarry Smith   }
9253a40ed3dSBarry Smith   PetscFunctionReturn(0);
926289bc588SBarry Smith }
9276ee01492SSatish Balay 
928e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
929289bc588SBarry Smith {
930dfbe8321SBarry Smith   PetscErrorCode ierr;
9316e111a19SKarl Rupp 
932606d414cSSatish Balay   PetscFunctionBegin;
933606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
934606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
9353a40ed3dSBarry Smith   PetscFunctionReturn(0);
936289bc588SBarry Smith }
937289bc588SBarry Smith /* ----------------------------------------------------------------*/
938e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
939289bc588SBarry Smith {
940c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
941ca15aa20SStefano Zampini   PetscScalar      *av;
94213f74950SBarry Smith   PetscInt         i,j,idx=0;
943ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
944c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
945ca15aa20SStefano Zampini #endif
946ca15aa20SStefano Zampini   PetscErrorCode   ierr;
947d6dfbf8fSBarry Smith 
9483a40ed3dSBarry Smith   PetscFunctionBegin;
949ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&av);CHKERRQ(ierr);
950289bc588SBarry Smith   if (!mat->roworiented) {
951dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
952289bc588SBarry Smith       for (j=0; j<n; j++) {
953cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
954cf9c20a2SJed Brown         if (PetscUnlikelyDebug(indexn[j] >= A->cmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
955289bc588SBarry Smith         for (i=0; i<m; i++) {
956cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
957cf9c20a2SJed Brown           if (PetscUnlikelyDebug(indexm[i] >= A->rmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
958ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
959289bc588SBarry Smith         }
960289bc588SBarry Smith       }
9613a40ed3dSBarry Smith     } else {
962289bc588SBarry Smith       for (j=0; j<n; j++) {
963cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
964cf9c20a2SJed Brown         if (PetscUnlikelyDebug(indexn[j] >= A->cmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
965289bc588SBarry Smith         for (i=0; i<m; i++) {
966cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
967cf9c20a2SJed Brown           if (PetscUnlikelyDebug(indexm[i] >= A->rmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
968ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
969289bc588SBarry Smith         }
970289bc588SBarry Smith       }
971289bc588SBarry Smith     }
9723a40ed3dSBarry Smith   } else {
973dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
974e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
975cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
976cf9c20a2SJed Brown         if (PetscUnlikelyDebug(indexm[i] >= A->rmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
977e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
978cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
979cf9c20a2SJed Brown           if (PetscUnlikelyDebug(indexn[j] >= A->cmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
980ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
981e8d4e0b9SBarry Smith         }
982e8d4e0b9SBarry Smith       }
9833a40ed3dSBarry Smith     } else {
984289bc588SBarry Smith       for (i=0; i<m; i++) {
985cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
986cf9c20a2SJed Brown         if (PetscUnlikelyDebug(indexm[i] >= A->rmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1);
987289bc588SBarry Smith         for (j=0; j<n; j++) {
988cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
989cf9c20a2SJed Brown           if (PetscUnlikelyDebug(indexn[j] >= A->cmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1);
990ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
991289bc588SBarry Smith         }
992289bc588SBarry Smith       }
993289bc588SBarry Smith     }
994e8d4e0b9SBarry Smith   }
995ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
996ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
997c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
998c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
999ca15aa20SStefano Zampini #endif
1000ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&av);CHKERRQ(ierr);
1001ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1002c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1003ca15aa20SStefano Zampini #endif
10043a40ed3dSBarry Smith   PetscFunctionReturn(0);
1005289bc588SBarry Smith }
1006e8d4e0b9SBarry Smith 
1007e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1008ae80bb75SLois Curfman McInnes {
1009ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1010ca15aa20SStefano Zampini   const PetscScalar *vv;
101113f74950SBarry Smith   PetscInt          i,j;
1012ca15aa20SStefano Zampini   PetscErrorCode    ierr;
1013ae80bb75SLois Curfman McInnes 
10143a40ed3dSBarry Smith   PetscFunctionBegin;
1015ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1016ae80bb75SLois Curfman McInnes   /* row-oriented output */
1017ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
101897e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1019e32f2f54SBarry Smith     if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D requested larger than number rows %D",indexm[i],A->rmap->n);
1020ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
10216f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1022e32f2f54SBarry Smith       if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column %D requested larger than number columns %D",indexn[j],A->cmap->n);
1023ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1024ae80bb75SLois Curfman McInnes     }
1025ae80bb75SLois Curfman McInnes   }
1026ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
10273a40ed3dSBarry Smith   PetscFunctionReturn(0);
1028ae80bb75SLois Curfman McInnes }
1029ae80bb75SLois Curfman McInnes 
1030289bc588SBarry Smith /* -----------------------------------------------------------------*/
1031289bc588SBarry Smith 
10328491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1033aabbc4fbSShri Abhyankar {
1034aabbc4fbSShri Abhyankar   PetscErrorCode    ierr;
10358491ab44SLisandro Dalcin   PetscBool         skipHeader;
10368491ab44SLisandro Dalcin   PetscViewerFormat format;
10378491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
10388491ab44SLisandro Dalcin   const PetscScalar *v;
10398491ab44SLisandro Dalcin   PetscScalar       *vwork;
1040aabbc4fbSShri Abhyankar 
1041aabbc4fbSShri Abhyankar   PetscFunctionBegin;
10428491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
10438491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
10448491ab44SLisandro Dalcin   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
10458491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1046aabbc4fbSShri Abhyankar 
10478491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
10488491ab44SLisandro Dalcin 
10498491ab44SLisandro Dalcin   /* write matrix header */
10508491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
10518491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
10528491ab44SLisandro Dalcin   if (!skipHeader) {ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);}
10538491ab44SLisandro Dalcin 
10548491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
10558491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
10568491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
10578491ab44SLisandro Dalcin     /* store row lengths for each row */
10588491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
10598491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
10608491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
10618491ab44SLisandro Dalcin     /* store column indices (zero start index) */
10628491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
10638491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
10648491ab44SLisandro Dalcin         iwork[k] = j;
10658491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
10668491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
10678491ab44SLisandro Dalcin   }
10688491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
10698491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
10708491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
10718491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
10728491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
10738491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
10748491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
10758491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
10768491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
10778491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
10788491ab44SLisandro Dalcin   PetscFunctionReturn(0);
10798491ab44SLisandro Dalcin }
10808491ab44SLisandro Dalcin 
10818491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
10828491ab44SLisandro Dalcin {
10838491ab44SLisandro Dalcin   PetscErrorCode ierr;
10848491ab44SLisandro Dalcin   PetscBool      skipHeader;
10858491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
10868491ab44SLisandro Dalcin   PetscInt       rows,cols;
10878491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
10888491ab44SLisandro Dalcin 
10898491ab44SLisandro Dalcin   PetscFunctionBegin;
10908491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
10918491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
10928491ab44SLisandro Dalcin 
10938491ab44SLisandro Dalcin   if (!skipHeader) {
10948491ab44SLisandro Dalcin     ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
10958491ab44SLisandro Dalcin     if (header[0] != MAT_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
10968491ab44SLisandro Dalcin     M = header[1]; N = header[2];
10978491ab44SLisandro Dalcin     if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M);
10988491ab44SLisandro Dalcin     if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N);
10998491ab44SLisandro Dalcin     nz = header[3];
11008491ab44SLisandro Dalcin     if (nz != MATRIX_BINARY_FORMAT_DENSE && nz < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %D in file",nz);
1101aabbc4fbSShri Abhyankar   } else {
11028491ab44SLisandro Dalcin     ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
11038491ab44SLisandro Dalcin     if (M < 0 || N < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Matrix binary file header was skipped, thus the user must specify the global sizes of input matrix");
11048491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1105e6324fbbSBarry Smith   }
1106aabbc4fbSShri Abhyankar 
11078491ab44SLisandro Dalcin   /* setup global sizes if not set */
11088491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
11098491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
11108491ab44SLisandro Dalcin   ierr = MatSetUp(mat);CHKERRQ(ierr);
11118491ab44SLisandro Dalcin   /* check if global sizes are correct */
11128491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
11138491ab44SLisandro Dalcin   if (M != rows || N != cols) SETERRQ4(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different sizes (%d, %d) than the input matrix (%d, %d)",M,N,rows,cols);
1114aabbc4fbSShri Abhyankar 
11158491ab44SLisandro Dalcin   ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
11168491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
11178491ab44SLisandro Dalcin   ierr = MatDenseGetArray(mat,&v);CHKERRQ(ierr);
11188491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
11198491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
11208491ab44SLisandro Dalcin     PetscInt nnz = m*N;
11218491ab44SLisandro Dalcin     /* read in matrix values */
11228491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&vwork);CHKERRQ(ierr);
11238491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
11248491ab44SLisandro Dalcin     /* store values in column major order */
11258491ab44SLisandro Dalcin     for (j=0; j<N; j++)
11268491ab44SLisandro Dalcin       for (i=0; i<m; i++)
11278491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
11288491ab44SLisandro Dalcin     ierr = PetscFree(vwork);CHKERRQ(ierr);
11298491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
11308491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
11318491ab44SLisandro Dalcin     /* read in row lengths */
11328491ab44SLisandro Dalcin     ierr = PetscMalloc1(m,&rlens);CHKERRQ(ierr);
11338491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
11348491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
11358491ab44SLisandro Dalcin     /* read in column indices and values */
11368491ab44SLisandro Dalcin     ierr = PetscMalloc2(nnz,&icols,nnz,&vwork);CHKERRQ(ierr);
11378491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
11388491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
11398491ab44SLisandro Dalcin     /* store values in column major order */
11408491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
11418491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
11428491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
11438491ab44SLisandro Dalcin     ierr = PetscFree(rlens);CHKERRQ(ierr);
11448491ab44SLisandro Dalcin     ierr = PetscFree2(icols,vwork);CHKERRQ(ierr);
1145aabbc4fbSShri Abhyankar   }
11468491ab44SLisandro Dalcin   ierr = MatDenseRestoreArray(mat,&v);CHKERRQ(ierr);
11478491ab44SLisandro Dalcin   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
11488491ab44SLisandro Dalcin   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1149aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1150aabbc4fbSShri Abhyankar }
1151aabbc4fbSShri Abhyankar 
1152eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1153eb91f321SVaclav Hapla {
1154eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1155eb91f321SVaclav Hapla   PetscErrorCode ierr;
1156eb91f321SVaclav Hapla 
1157eb91f321SVaclav Hapla   PetscFunctionBegin;
1158eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1159eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1160eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
1161eb91f321SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1162eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1163eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1164eb91f321SVaclav Hapla   if (isbinary) {
11658491ab44SLisandro Dalcin     ierr = MatLoad_Dense_Binary(newMat,viewer);CHKERRQ(ierr);
1166eb91f321SVaclav Hapla   } else if (ishdf5) {
1167eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
1168eb91f321SVaclav Hapla     ierr = MatLoad_Dense_HDF5(newMat,viewer);CHKERRQ(ierr);
1169eb91f321SVaclav Hapla #else
1170eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1171eb91f321SVaclav Hapla #endif
1172eb91f321SVaclav Hapla   } else {
1173eb91f321SVaclav Hapla     SETERRQ2(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"Viewer type %s not yet supported for reading %s matrices",((PetscObject)viewer)->type_name,((PetscObject)newMat)->type_name);
1174eb91f321SVaclav Hapla   }
1175eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1176eb91f321SVaclav Hapla }
1177eb91f321SVaclav Hapla 
11786849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1179289bc588SBarry Smith {
1180932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1181dfbe8321SBarry Smith   PetscErrorCode    ierr;
118213f74950SBarry Smith   PetscInt          i,j;
11832dcb1b2aSMatthew Knepley   const char        *name;
1184ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1185f3ef73ceSBarry Smith   PetscViewerFormat format;
11865f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1187ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
11885f481a85SSatish Balay #endif
1189932b0c3eSLois Curfman McInnes 
11903a40ed3dSBarry Smith   PetscFunctionBegin;
1191ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1192b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1193456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
11943a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1195fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1196d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1197d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1198ca15aa20SStefano Zampini       v    = av + i;
119977431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1200d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1201aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1202329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
120357622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1204329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
120557622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
12066831982aSBarry Smith         }
120780cd9d93SLois Curfman McInnes #else
12086831982aSBarry Smith         if (*v) {
120957622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
12106831982aSBarry Smith         }
121180cd9d93SLois Curfman McInnes #endif
12121b807ce4Svictorle         v += a->lda;
121380cd9d93SLois Curfman McInnes       }
1214b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
121580cd9d93SLois Curfman McInnes     }
1216d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
12173a40ed3dSBarry Smith   } else {
1218d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1219aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
122047989497SBarry Smith     /* determine if matrix has all real values */
1221ca15aa20SStefano Zampini     v = av;
1222d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1223ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
122447989497SBarry Smith     }
122547989497SBarry Smith #endif
1226fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
12273a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1228d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1229d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1230fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1231ffac6cdbSBarry Smith     }
1232ffac6cdbSBarry Smith 
1233d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1234ca15aa20SStefano Zampini       v = av + i;
1235d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1236aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
123747989497SBarry Smith         if (allreal) {
1238c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
123947989497SBarry Smith         } else {
1240c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
124147989497SBarry Smith         }
1242289bc588SBarry Smith #else
1243c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1244289bc588SBarry Smith #endif
12451b807ce4Svictorle         v += a->lda;
1246289bc588SBarry Smith       }
1247b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1248289bc588SBarry Smith     }
1249fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1250b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1251ffac6cdbSBarry Smith     }
1252d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1253da3a660dSBarry Smith   }
1254ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1255b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
12563a40ed3dSBarry Smith   PetscFunctionReturn(0);
1257289bc588SBarry Smith }
1258289bc588SBarry Smith 
12599804daf3SBarry Smith #include <petscdraw.h>
1260e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1261f1af5d2fSBarry Smith {
1262f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
12636849ba73SBarry Smith   PetscErrorCode    ierr;
1264383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1265383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1266ca15aa20SStefano Zampini   const PetscScalar *v;
1267b0a32e0cSBarry Smith   PetscViewer       viewer;
1268b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1269f3ef73ceSBarry Smith   PetscViewerFormat format;
1270f1af5d2fSBarry Smith 
1271f1af5d2fSBarry Smith   PetscFunctionBegin;
1272f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1273b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1274b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1275f1af5d2fSBarry Smith 
1276f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1277ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1278fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1279383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1280f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1281f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1282383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1283f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1284f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1285f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1286ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1287ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1288ca15aa20SStefano Zampini         else continue;
1289b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1290f1af5d2fSBarry Smith       }
1291f1af5d2fSBarry Smith     }
1292383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1293f1af5d2fSBarry Smith   } else {
1294f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1295f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1296b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1297b05fc000SLisandro Dalcin     PetscDraw popup;
1298b05fc000SLisandro Dalcin 
1299f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1300f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1301f1af5d2fSBarry Smith     }
1302383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1303b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
130445f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1305383922c3SLisandro Dalcin 
1306383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1307f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1308f1af5d2fSBarry Smith       x_l = j;
1309f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1310f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1311f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1312f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1313b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1314b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1315f1af5d2fSBarry Smith       }
1316f1af5d2fSBarry Smith     }
1317383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1318f1af5d2fSBarry Smith   }
1319ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1320f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1321f1af5d2fSBarry Smith }
1322f1af5d2fSBarry Smith 
1323e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1324f1af5d2fSBarry Smith {
1325b0a32e0cSBarry Smith   PetscDraw      draw;
1326ace3abfcSBarry Smith   PetscBool      isnull;
1327329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1328dfbe8321SBarry Smith   PetscErrorCode ierr;
1329f1af5d2fSBarry Smith 
1330f1af5d2fSBarry Smith   PetscFunctionBegin;
1331b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1332b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1333abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1334f1af5d2fSBarry Smith 
1335d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1336f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1337b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1338832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1339b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
13400298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1341832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1342f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1343f1af5d2fSBarry Smith }
1344f1af5d2fSBarry Smith 
1345dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1346932b0c3eSLois Curfman McInnes {
1347dfbe8321SBarry Smith   PetscErrorCode ierr;
1348ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1349932b0c3eSLois Curfman McInnes 
13503a40ed3dSBarry Smith   PetscFunctionBegin;
1351251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1352251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1353251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
13540f5bd95cSBarry Smith 
1355c45a1595SBarry Smith   if (iascii) {
1356c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
13570f5bd95cSBarry Smith   } else if (isbinary) {
1358637a0070SStefano Zampini     ierr = MatView_Dense_Binary(A,viewer);CHKERRQ(ierr);
1359f1af5d2fSBarry Smith   } else if (isdraw) {
1360f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1361932b0c3eSLois Curfman McInnes   }
13623a40ed3dSBarry Smith   PetscFunctionReturn(0);
1363932b0c3eSLois Curfman McInnes }
1364289bc588SBarry Smith 
1365637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array)
1366d3042a70SBarry Smith {
1367d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1368d3042a70SBarry Smith 
1369d3042a70SBarry Smith   PetscFunctionBegin;
13705ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
13715ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
13725ea7661aSPierre Jolivet   if (a->unplacedarray) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreArray() first");
1373d3042a70SBarry Smith   a->unplacedarray       = a->v;
1374d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1375d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1376637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1377ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1378c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1379ca15aa20SStefano Zampini #endif
1380d3042a70SBarry Smith   PetscFunctionReturn(0);
1381d3042a70SBarry Smith }
1382d3042a70SBarry Smith 
1383d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1384d3042a70SBarry Smith {
1385d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1386d3042a70SBarry Smith 
1387d3042a70SBarry Smith   PetscFunctionBegin;
13885ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
13895ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1390d3042a70SBarry Smith   a->v             = a->unplacedarray;
1391d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1392d3042a70SBarry Smith   a->unplacedarray = NULL;
1393ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1394c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1395ca15aa20SStefano Zampini #endif
1396d3042a70SBarry Smith   PetscFunctionReturn(0);
1397d3042a70SBarry Smith }
1398d3042a70SBarry Smith 
1399d5ea218eSStefano Zampini static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A,const PetscScalar *array)
1400d5ea218eSStefano Zampini {
1401d5ea218eSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1402d5ea218eSStefano Zampini   PetscErrorCode ierr;
1403d5ea218eSStefano Zampini 
1404d5ea218eSStefano Zampini   PetscFunctionBegin;
14055ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
14065ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1407d5ea218eSStefano Zampini   if (!a->user_alloc) { ierr = PetscFree(a->v);CHKERRQ(ierr); }
1408d5ea218eSStefano Zampini   a->v           = (PetscScalar*) array;
1409d5ea218eSStefano Zampini   a->user_alloc  = PETSC_FALSE;
1410d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1411d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1412d5ea218eSStefano Zampini #endif
1413d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1414d5ea218eSStefano Zampini }
1415d5ea218eSStefano Zampini 
1416ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1417289bc588SBarry Smith {
1418ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1419dfbe8321SBarry Smith   PetscErrorCode ierr;
142090f02eecSBarry Smith 
14213a40ed3dSBarry Smith   PetscFunctionBegin;
1422aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1423d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1424a5a9c739SBarry Smith #endif
142505b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1426a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1427abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
14286857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1429637a0070SStefano Zampini   if (!l->unplaced_user_alloc) {ierr = PetscFree(l->unplacedarray);CHKERRQ(ierr);}
14305ea7661aSPierre Jolivet   if (l->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
14315ea7661aSPierre Jolivet   if (l->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
14326947451fSStefano Zampini   ierr = VecDestroy(&l->cvec);CHKERRQ(ierr);
14335ea7661aSPierre Jolivet   ierr = MatDestroy(&l->cmat);CHKERRQ(ierr);
1434bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1435dbd8c25aSHong Zhang 
1436f4259b30SLisandro Dalcin   ierr = PetscObjectChangeTypeName((PetscObject)mat,NULL);CHKERRQ(ierr);
143749a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1438ad16ce7aSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseSetLDA_C",NULL);CHKERRQ(ierr);
1439bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
144052c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
1441d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1442d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
1443d5ea218eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseReplaceArray_C",NULL);CHKERRQ(ierr);
144452c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL);CHKERRQ(ierr);
144552c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL);CHKERRQ(ierr);
14466947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayWrite_C",NULL);CHKERRQ(ierr);
14476947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayWrite_C",NULL);CHKERRQ(ierr);
14488baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
14498baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
14508baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
14518baccfbdSHong Zhang #endif
1452d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
1453d24d4204SJose E. Roman   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_scalapack_C",NULL);CHKERRQ(ierr);
1454d24d4204SJose E. Roman #endif
14552bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
14562bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL);CHKERRQ(ierr);
14574222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL);CHKERRQ(ierr);
14584222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL);CHKERRQ(ierr);
14592bf066beSStefano Zampini #endif
1460bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
14614222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14624222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL);CHKERRQ(ierr);
14634222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
14644222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
146552c5f739Sprj- 
146686aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
146786aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
14686947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVec_C",NULL);CHKERRQ(ierr);
14696947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVec_C",NULL);CHKERRQ(ierr);
14706947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecRead_C",NULL);CHKERRQ(ierr);
14716947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecRead_C",NULL);CHKERRQ(ierr);
14726947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecWrite_C",NULL);CHKERRQ(ierr);
14736947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecWrite_C",NULL);CHKERRQ(ierr);
14745ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetSubMatrix_C",NULL);CHKERRQ(ierr);
14755ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreSubMatrix_C",NULL);CHKERRQ(ierr);
14763a40ed3dSBarry Smith   PetscFunctionReturn(0);
1477289bc588SBarry Smith }
1478289bc588SBarry Smith 
1479e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1480289bc588SBarry Smith {
1481c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
14826849ba73SBarry Smith   PetscErrorCode ierr;
14836536e3caSStefano Zampini   PetscInt       k,j,m = A->rmap->n, M = mat->lda, n = A->cmap->n;
148487828ca2SBarry Smith   PetscScalar    *v,tmp;
148548b35521SBarry Smith 
14863a40ed3dSBarry Smith   PetscFunctionBegin;
14876536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
14886536e3caSStefano Zampini     if (m == n) { /* in place transpose */
1489ca15aa20SStefano Zampini       ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1490d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1491289bc588SBarry Smith         for (k=0; k<j; k++) {
14921b807ce4Svictorle           tmp        = v[j + k*M];
14931b807ce4Svictorle           v[j + k*M] = v[k + j*M];
14941b807ce4Svictorle           v[k + j*M] = tmp;
1495289bc588SBarry Smith         }
1496289bc588SBarry Smith       }
1497ca15aa20SStefano Zampini       ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
14986536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
14996536e3caSStefano Zampini       PetscScalar *v2;
15006536e3caSStefano Zampini       PetscLayout tmplayout;
15016536e3caSStefano Zampini 
15026536e3caSStefano Zampini       ierr = PetscMalloc1((size_t)m*n,&v2);CHKERRQ(ierr);
15036536e3caSStefano Zampini       ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
15046536e3caSStefano Zampini       for (j=0; j<n; j++) {
15056536e3caSStefano Zampini         for (k=0; k<m; k++) v2[j + (size_t)k*n] = v[k + (size_t)j*M];
15066536e3caSStefano Zampini       }
15076536e3caSStefano Zampini       ierr = PetscArraycpy(v,v2,(size_t)m*n);CHKERRQ(ierr);
15086536e3caSStefano Zampini       ierr = PetscFree(v2);CHKERRQ(ierr);
15096536e3caSStefano Zampini       ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
15106536e3caSStefano Zampini       /* cleanup size dependent quantities */
15116536e3caSStefano Zampini       ierr = VecDestroy(&mat->cvec);CHKERRQ(ierr);
15126536e3caSStefano Zampini       ierr = MatDestroy(&mat->cmat);CHKERRQ(ierr);
15136536e3caSStefano Zampini       ierr = PetscFree(mat->pivots);CHKERRQ(ierr);
15146536e3caSStefano Zampini       ierr = PetscFree(mat->fwork);CHKERRQ(ierr);
15156536e3caSStefano Zampini       ierr = MatDestroy(&mat->ptapwork);CHKERRQ(ierr);
15166536e3caSStefano Zampini       /* swap row/col layouts */
15176536e3caSStefano Zampini       mat->lda  = n;
15186536e3caSStefano Zampini       tmplayout = A->rmap;
15196536e3caSStefano Zampini       A->rmap   = A->cmap;
15206536e3caSStefano Zampini       A->cmap   = tmplayout;
15216536e3caSStefano Zampini     }
15223a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1523d3e5ee88SLois Curfman McInnes     Mat          tmat;
1524ec8511deSBarry Smith     Mat_SeqDense *tmatd;
152587828ca2SBarry Smith     PetscScalar  *v2;
1526af36a384SStefano Zampini     PetscInt     M2;
1527ea709b57SSatish Balay 
15286536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
1529ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1530d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
15317adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
15320298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1533ca15aa20SStefano Zampini     } else tmat = *matout;
1534ca15aa20SStefano Zampini 
1535ca15aa20SStefano Zampini     ierr  = MatDenseGetArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
1536ca15aa20SStefano Zampini     ierr  = MatDenseGetArray(tmat,&v2);CHKERRQ(ierr);
1537ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1538ca15aa20SStefano Zampini     M2    = tmatd->lda;
1539d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1540af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1541d3e5ee88SLois Curfman McInnes     }
1542ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(tmat,&v2);CHKERRQ(ierr);
1543ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
15446d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15456d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15466536e3caSStefano Zampini     *matout = tmat;
154748b35521SBarry Smith   }
15483a40ed3dSBarry Smith   PetscFunctionReturn(0);
1549289bc588SBarry Smith }
1550289bc588SBarry Smith 
1551e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1552289bc588SBarry Smith {
1553c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1554c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1555ca15aa20SStefano Zampini   PetscInt          i;
1556ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
1557ca15aa20SStefano Zampini   PetscErrorCode    ierr;
15589ea5d5aeSSatish Balay 
15593a40ed3dSBarry Smith   PetscFunctionBegin;
1560d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1561d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1562ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A1,&v1);CHKERRQ(ierr);
1563ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A2,&v2);CHKERRQ(ierr);
1564ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
1565ca15aa20SStefano Zampini     ierr = PetscArraycmp(v1,v2,A1->rmap->n,flg);CHKERRQ(ierr);
1566ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1567ca15aa20SStefano Zampini     v1 += mat1->lda;
1568ca15aa20SStefano Zampini     v2 += mat2->lda;
15691b807ce4Svictorle   }
1570ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A1,&v1);CHKERRQ(ierr);
1571ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A2,&v2);CHKERRQ(ierr);
157277c4ece6SBarry Smith   *flg = PETSC_TRUE;
15733a40ed3dSBarry Smith   PetscFunctionReturn(0);
1574289bc588SBarry Smith }
1575289bc588SBarry Smith 
1576e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1577289bc588SBarry Smith {
1578c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
157913f74950SBarry Smith   PetscInt          i,n,len;
1580ca15aa20SStefano Zampini   PetscScalar       *x;
1581ca15aa20SStefano Zampini   const PetscScalar *vv;
1582ca15aa20SStefano Zampini   PetscErrorCode    ierr;
158344cd7ae7SLois Curfman McInnes 
15843a40ed3dSBarry Smith   PetscFunctionBegin;
15857a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
15861ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1587d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1588ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1589e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
159044cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1591ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1592289bc588SBarry Smith   }
1593ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
15941ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
15953a40ed3dSBarry Smith   PetscFunctionReturn(0);
1596289bc588SBarry Smith }
1597289bc588SBarry Smith 
1598e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1599289bc588SBarry Smith {
1600c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1601f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1602ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1603dfbe8321SBarry Smith   PetscErrorCode    ierr;
1604d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
160555659b69SBarry Smith 
16063a40ed3dSBarry Smith   PetscFunctionBegin;
1607ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&vv);CHKERRQ(ierr);
160828988994SBarry Smith   if (ll) {
16097a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1610f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1611e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1612da3a660dSBarry Smith     for (i=0; i<m; i++) {
1613da3a660dSBarry Smith       x = l[i];
1614ca15aa20SStefano Zampini       v = vv + i;
1615b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1616da3a660dSBarry Smith     }
1617f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1618eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1619da3a660dSBarry Smith   }
162028988994SBarry Smith   if (rr) {
16217a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1622f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1623e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1624da3a660dSBarry Smith     for (i=0; i<n; i++) {
1625da3a660dSBarry Smith       x = r[i];
1626ca15aa20SStefano Zampini       v = vv + i*mat->lda;
16272205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1628da3a660dSBarry Smith     }
1629f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1630eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1631da3a660dSBarry Smith   }
1632ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&vv);CHKERRQ(ierr);
16333a40ed3dSBarry Smith   PetscFunctionReturn(0);
1634289bc588SBarry Smith }
1635289bc588SBarry Smith 
1636ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1637289bc588SBarry Smith {
1638c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1639ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1640329f5518SBarry Smith   PetscReal         sum  = 0.0;
1641d0f46423SBarry Smith   PetscInt          lda  =mat->lda,m=A->rmap->n,i,j;
1642efee365bSSatish Balay   PetscErrorCode    ierr;
164355659b69SBarry Smith 
16443a40ed3dSBarry Smith   PetscFunctionBegin;
1645ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
1646ca15aa20SStefano Zampini   v    = vv;
1647289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1648a5ce6ee0Svictorle     if (lda>m) {
1649d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1650ca15aa20SStefano Zampini         v = vv+j*lda;
1651a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1652a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1653a5ce6ee0Svictorle         }
1654a5ce6ee0Svictorle       }
1655a5ce6ee0Svictorle     } else {
1656570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1657570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
165873cf7048SBarry Smith       PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&cnt,v,&one));
1659570b7f6dSBarry Smith     }
1660570b7f6dSBarry Smith #else
1661d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1662329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1663289bc588SBarry Smith       }
1664a5ce6ee0Svictorle     }
16658f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1666570b7f6dSBarry Smith #endif
1667dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16683a40ed3dSBarry Smith   } else if (type == NORM_1) {
1669064f8208SBarry Smith     *nrm = 0.0;
1670d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1671ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
1672289bc588SBarry Smith       sum = 0.0;
1673d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
167433a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1675289bc588SBarry Smith       }
1676064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1677289bc588SBarry Smith     }
1678eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16793a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1680064f8208SBarry Smith     *nrm = 0.0;
1681d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1682ca15aa20SStefano Zampini       v   = vv + j;
1683289bc588SBarry Smith       sum = 0.0;
1684d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
16851b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1686289bc588SBarry Smith       }
1687064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1688289bc588SBarry Smith     }
1689eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1690e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
1691ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
16923a40ed3dSBarry Smith   PetscFunctionReturn(0);
1693289bc588SBarry Smith }
1694289bc588SBarry Smith 
1695e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1696289bc588SBarry Smith {
1697c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
169863ba0a88SBarry Smith   PetscErrorCode ierr;
169967e560aaSBarry Smith 
17003a40ed3dSBarry Smith   PetscFunctionBegin;
1701b5a2b587SKris Buschelman   switch (op) {
1702b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
17034e0d8c25SBarry Smith     aij->roworiented = flg;
1704b5a2b587SKris Buschelman     break;
1705512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1706b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
17073971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
17088c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
170913fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1710b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1711b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
17120f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
17135021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
1714071fcb05SBarry Smith   case MAT_SORTED_FULL:
17155021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
17165021d80fSJed Brown     break;
17175021d80fSJed Brown   case MAT_SPD:
171877e54ba9SKris Buschelman   case MAT_SYMMETRIC:
171977e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
17209a4540c5SBarry Smith   case MAT_HERMITIAN:
17219a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
17225021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
172377e54ba9SKris Buschelman     break;
1724b5a2b587SKris Buschelman   default:
1725e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
17263a40ed3dSBarry Smith   }
17273a40ed3dSBarry Smith   PetscFunctionReturn(0);
1728289bc588SBarry Smith }
1729289bc588SBarry Smith 
1730e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
17316f0a148fSBarry Smith {
1732ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
17336849ba73SBarry Smith   PetscErrorCode ierr;
1734d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
1735ca15aa20SStefano Zampini   PetscScalar    *v;
17363a40ed3dSBarry Smith 
17373a40ed3dSBarry Smith   PetscFunctionBegin;
1738ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1739a5ce6ee0Svictorle   if (lda>m) {
1740d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1741ca15aa20SStefano Zampini       ierr = PetscArrayzero(v+j*lda,m);CHKERRQ(ierr);
1742a5ce6ee0Svictorle     }
1743a5ce6ee0Svictorle   } else {
1744ca15aa20SStefano Zampini     ierr = PetscArrayzero(v,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
1745a5ce6ee0Svictorle   }
1746ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17473a40ed3dSBarry Smith   PetscFunctionReturn(0);
17486f0a148fSBarry Smith }
17496f0a148fSBarry Smith 
1750e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
17516f0a148fSBarry Smith {
175297b48c8fSBarry Smith   PetscErrorCode    ierr;
1753ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1754b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
1755ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
175697b48c8fSBarry Smith   const PetscScalar *xx;
175755659b69SBarry Smith 
17583a40ed3dSBarry Smith   PetscFunctionBegin;
175976bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1760b9679d65SBarry Smith     for (i=0; i<N; i++) {
1761b9679d65SBarry Smith       if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1762b9679d65SBarry Smith       if (rows[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D requested to be zeroed greater than or equal number of rows %D",rows[i],A->rmap->n);
1763b9679d65SBarry Smith     }
176476bd3646SJed Brown   }
1765ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1766b9679d65SBarry Smith 
176797b48c8fSBarry Smith   /* fix right hand side if needed */
176897b48c8fSBarry Smith   if (x && b) {
176997b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
177097b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
17712205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
177297b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
177397b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
177497b48c8fSBarry Smith   }
177597b48c8fSBarry Smith 
1776ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
17776f0a148fSBarry Smith   for (i=0; i<N; i++) {
1778ca15aa20SStefano Zampini     slot = v + rows[i];
1779b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
17806f0a148fSBarry Smith   }
1781f4df32b1SMatthew Knepley   if (diag != 0.0) {
1782b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
17836f0a148fSBarry Smith     for (i=0; i<N; i++) {
1784ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1785f4df32b1SMatthew Knepley       *slot = diag;
17866f0a148fSBarry Smith     }
17876f0a148fSBarry Smith   }
1788ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17893a40ed3dSBarry Smith   PetscFunctionReturn(0);
17906f0a148fSBarry Smith }
1791557bce09SLois Curfman McInnes 
179249a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
179349a6ff4bSBarry Smith {
179449a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
179549a6ff4bSBarry Smith 
179649a6ff4bSBarry Smith   PetscFunctionBegin;
179749a6ff4bSBarry Smith   *lda = mat->lda;
179849a6ff4bSBarry Smith   PetscFunctionReturn(0);
179949a6ff4bSBarry Smith }
180049a6ff4bSBarry Smith 
1801637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array)
180264e87e97SBarry Smith {
1803c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
18043a40ed3dSBarry Smith 
18053a40ed3dSBarry Smith   PetscFunctionBegin;
1806616b8fbbSStefano Zampini   if (mat->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
180764e87e97SBarry Smith   *array = mat->v;
18083a40ed3dSBarry Smith   PetscFunctionReturn(0);
180964e87e97SBarry Smith }
18100754003eSLois Curfman McInnes 
1811637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array)
1812ff14e315SSatish Balay {
18133a40ed3dSBarry Smith   PetscFunctionBegin;
1814637a0070SStefano Zampini   *array = NULL;
18153a40ed3dSBarry Smith   PetscFunctionReturn(0);
1816ff14e315SSatish Balay }
18170754003eSLois Curfman McInnes 
1818dec5eb66SMatthew G Knepley /*@C
181949a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
182049a6ff4bSBarry Smith 
1821ad16ce7aSStefano Zampini    Not collective
182249a6ff4bSBarry Smith 
182349a6ff4bSBarry Smith    Input Parameter:
182449a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
182549a6ff4bSBarry Smith 
182649a6ff4bSBarry Smith    Output Parameter:
182749a6ff4bSBarry Smith .   lda - the leading dimension
182849a6ff4bSBarry Smith 
182949a6ff4bSBarry Smith    Level: intermediate
183049a6ff4bSBarry Smith 
1831ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseSetLDA()
183249a6ff4bSBarry Smith @*/
183349a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
183449a6ff4bSBarry Smith {
183549a6ff4bSBarry Smith   PetscErrorCode ierr;
183649a6ff4bSBarry Smith 
183749a6ff4bSBarry Smith   PetscFunctionBegin;
1838d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1839d5ea218eSStefano Zampini   PetscValidPointer(lda,2);
184049a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
184149a6ff4bSBarry Smith   PetscFunctionReturn(0);
184249a6ff4bSBarry Smith }
184349a6ff4bSBarry Smith 
184449a6ff4bSBarry Smith /*@C
1845ad16ce7aSStefano Zampini    MatDenseSetLDA - Sets the leading dimension of the array used by the dense matrix
1846ad16ce7aSStefano Zampini 
1847ad16ce7aSStefano Zampini    Not collective
1848ad16ce7aSStefano Zampini 
1849ad16ce7aSStefano Zampini    Input Parameter:
1850ad16ce7aSStefano Zampini +  mat - a MATSEQDENSE or MATMPIDENSE matrix
1851ad16ce7aSStefano Zampini -  lda - the leading dimension
1852ad16ce7aSStefano Zampini 
1853ad16ce7aSStefano Zampini    Level: intermediate
1854ad16ce7aSStefano Zampini 
1855ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetLDA()
1856ad16ce7aSStefano Zampini @*/
1857ad16ce7aSStefano Zampini PetscErrorCode  MatDenseSetLDA(Mat A,PetscInt lda)
1858ad16ce7aSStefano Zampini {
1859ad16ce7aSStefano Zampini   PetscErrorCode ierr;
1860ad16ce7aSStefano Zampini 
1861ad16ce7aSStefano Zampini   PetscFunctionBegin;
1862ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1863ad16ce7aSStefano Zampini   ierr = PetscTryMethod(A,"MatDenseSetLDA_C",(Mat,PetscInt),(A,lda));CHKERRQ(ierr);
1864ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
1865ad16ce7aSStefano Zampini }
1866ad16ce7aSStefano Zampini 
1867ad16ce7aSStefano Zampini /*@C
18686947451fSStefano Zampini    MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored
186973a71a0fSBarry Smith 
18708572280aSBarry Smith    Logically Collective on Mat
187173a71a0fSBarry Smith 
187273a71a0fSBarry Smith    Input Parameter:
18736947451fSStefano Zampini .  mat - a dense matrix
187473a71a0fSBarry Smith 
187573a71a0fSBarry Smith    Output Parameter:
187673a71a0fSBarry Smith .   array - pointer to the data
187773a71a0fSBarry Smith 
187873a71a0fSBarry Smith    Level: intermediate
187973a71a0fSBarry Smith 
18806947451fSStefano Zampini .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
188173a71a0fSBarry Smith @*/
18828c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
188373a71a0fSBarry Smith {
188473a71a0fSBarry Smith   PetscErrorCode ierr;
188573a71a0fSBarry Smith 
188673a71a0fSBarry Smith   PetscFunctionBegin;
1887d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1888d5ea218eSStefano Zampini   PetscValidPointer(array,2);
18898c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
189073a71a0fSBarry Smith   PetscFunctionReturn(0);
189173a71a0fSBarry Smith }
189273a71a0fSBarry Smith 
1893dec5eb66SMatthew G Knepley /*@C
1894579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
189573a71a0fSBarry Smith 
18968572280aSBarry Smith    Logically Collective on Mat
18978572280aSBarry Smith 
18988572280aSBarry Smith    Input Parameters:
18996947451fSStefano Zampini +  mat - a dense matrix
1900a2b725a8SWilliam Gropp -  array - pointer to the data
19018572280aSBarry Smith 
19028572280aSBarry Smith    Level: intermediate
19038572280aSBarry Smith 
19046947451fSStefano Zampini .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
19058572280aSBarry Smith @*/
19068572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
19078572280aSBarry Smith {
19088572280aSBarry Smith   PetscErrorCode ierr;
19098572280aSBarry Smith 
19108572280aSBarry Smith   PetscFunctionBegin;
1911d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1912d5ea218eSStefano Zampini   PetscValidPointer(array,2);
19138572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
19148572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
1915637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1916637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1917637a0070SStefano Zampini #endif
19188572280aSBarry Smith   PetscFunctionReturn(0);
19198572280aSBarry Smith }
19208572280aSBarry Smith 
19218572280aSBarry Smith /*@C
19226947451fSStefano Zampini    MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored
19238572280aSBarry Smith 
19248572280aSBarry Smith    Not Collective
19258572280aSBarry Smith 
19268572280aSBarry Smith    Input Parameter:
19276947451fSStefano Zampini .  mat - a dense matrix
19288572280aSBarry Smith 
19298572280aSBarry Smith    Output Parameter:
19308572280aSBarry Smith .   array - pointer to the data
19318572280aSBarry Smith 
19328572280aSBarry Smith    Level: intermediate
19338572280aSBarry Smith 
19346947451fSStefano Zampini .seealso: MatDenseRestoreArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
19358572280aSBarry Smith @*/
19368572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
19378572280aSBarry Smith {
19388572280aSBarry Smith   PetscErrorCode ierr;
19398572280aSBarry Smith 
19408572280aSBarry Smith   PetscFunctionBegin;
1941d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1942d5ea218eSStefano Zampini   PetscValidPointer(array,2);
19438572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
19448572280aSBarry Smith   PetscFunctionReturn(0);
19458572280aSBarry Smith }
19468572280aSBarry Smith 
19478572280aSBarry Smith /*@C
19486947451fSStefano Zampini    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead()
19498572280aSBarry Smith 
195073a71a0fSBarry Smith    Not Collective
195173a71a0fSBarry Smith 
195273a71a0fSBarry Smith    Input Parameters:
19536947451fSStefano Zampini +  mat - a dense matrix
1954a2b725a8SWilliam Gropp -  array - pointer to the data
195573a71a0fSBarry Smith 
195673a71a0fSBarry Smith    Level: intermediate
195773a71a0fSBarry Smith 
19586947451fSStefano Zampini .seealso: MatDenseGetArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
195973a71a0fSBarry Smith @*/
19608572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
196173a71a0fSBarry Smith {
196273a71a0fSBarry Smith   PetscErrorCode ierr;
196373a71a0fSBarry Smith 
196473a71a0fSBarry Smith   PetscFunctionBegin;
1965d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1966d5ea218eSStefano Zampini   PetscValidPointer(array,2);
19678572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
196873a71a0fSBarry Smith   PetscFunctionReturn(0);
196973a71a0fSBarry Smith }
197073a71a0fSBarry Smith 
19716947451fSStefano Zampini /*@C
19726947451fSStefano Zampini    MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored
19736947451fSStefano Zampini 
19746947451fSStefano Zampini    Not Collective
19756947451fSStefano Zampini 
19766947451fSStefano Zampini    Input Parameter:
19776947451fSStefano Zampini .  mat - a dense matrix
19786947451fSStefano Zampini 
19796947451fSStefano Zampini    Output Parameter:
19806947451fSStefano Zampini .   array - pointer to the data
19816947451fSStefano Zampini 
19826947451fSStefano Zampini    Level: intermediate
19836947451fSStefano Zampini 
19846947451fSStefano Zampini .seealso: MatDenseRestoreArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
19856947451fSStefano Zampini @*/
19866947451fSStefano Zampini PetscErrorCode  MatDenseGetArrayWrite(Mat A,PetscScalar **array)
19876947451fSStefano Zampini {
19886947451fSStefano Zampini   PetscErrorCode ierr;
19896947451fSStefano Zampini 
19906947451fSStefano Zampini   PetscFunctionBegin;
1991d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1992d5ea218eSStefano Zampini   PetscValidPointer(array,2);
19936947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
19946947451fSStefano Zampini   PetscFunctionReturn(0);
19956947451fSStefano Zampini }
19966947451fSStefano Zampini 
19976947451fSStefano Zampini /*@C
19986947451fSStefano Zampini    MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite()
19996947451fSStefano Zampini 
20006947451fSStefano Zampini    Not Collective
20016947451fSStefano Zampini 
20026947451fSStefano Zampini    Input Parameters:
20036947451fSStefano Zampini +  mat - a dense matrix
20046947451fSStefano Zampini -  array - pointer to the data
20056947451fSStefano Zampini 
20066947451fSStefano Zampini    Level: intermediate
20076947451fSStefano Zampini 
20086947451fSStefano Zampini .seealso: MatDenseGetArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
20096947451fSStefano Zampini @*/
20106947451fSStefano Zampini PetscErrorCode  MatDenseRestoreArrayWrite(Mat A,PetscScalar **array)
20116947451fSStefano Zampini {
20126947451fSStefano Zampini   PetscErrorCode ierr;
20136947451fSStefano Zampini 
20146947451fSStefano Zampini   PetscFunctionBegin;
2015d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2016d5ea218eSStefano Zampini   PetscValidPointer(array,2);
20176947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
20186947451fSStefano Zampini   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
20196947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
20206947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
20216947451fSStefano Zampini #endif
20226947451fSStefano Zampini   PetscFunctionReturn(0);
20236947451fSStefano Zampini }
20246947451fSStefano Zampini 
20257dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
20260754003eSLois Curfman McInnes {
2027c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
20286849ba73SBarry Smith   PetscErrorCode ierr;
2029ca15aa20SStefano Zampini   PetscInt       i,j,nrows,ncols,blda;
20305d0c19d7SBarry Smith   const PetscInt *irow,*icol;
203187828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
20320754003eSLois Curfman McInnes   Mat            newmat;
20330754003eSLois Curfman McInnes 
20343a40ed3dSBarry Smith   PetscFunctionBegin;
203578b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
203678b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
2037e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2038e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
20390754003eSLois Curfman McInnes 
2040182d2002SSatish Balay   /* Check submatrixcall */
2041182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
204213f74950SBarry Smith     PetscInt n_cols,n_rows;
2043182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
204421a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2045f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
2046c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
204721a2c019SBarry Smith     }
2048182d2002SSatish Balay     newmat = *B;
2049182d2002SSatish Balay   } else {
20500754003eSLois Curfman McInnes     /* Create and fill new matrix */
2051ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
2052f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
20537adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
20540298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
2055182d2002SSatish Balay   }
2056182d2002SSatish Balay 
2057182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
2058ca15aa20SStefano Zampini   ierr = MatDenseGetArray(newmat,&bv);CHKERRQ(ierr);
2059ca15aa20SStefano Zampini   ierr = MatDenseGetLDA(newmat,&blda);CHKERRQ(ierr);
2060182d2002SSatish Balay   for (i=0; i<ncols; i++) {
20616de62eeeSBarry Smith     av = v + mat->lda*icol[i];
2062ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
2063ca15aa20SStefano Zampini     bv += blda;
20640754003eSLois Curfman McInnes   }
2065ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(newmat,&bv);CHKERRQ(ierr);
2066182d2002SSatish Balay 
2067182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
20686d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20696d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20700754003eSLois Curfman McInnes 
20710754003eSLois Curfman McInnes   /* Free work space */
207278b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
207378b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2074182d2002SSatish Balay   *B   = newmat;
20753a40ed3dSBarry Smith   PetscFunctionReturn(0);
20760754003eSLois Curfman McInnes }
20770754003eSLois Curfman McInnes 
20787dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2079905e6a2fSBarry Smith {
20806849ba73SBarry Smith   PetscErrorCode ierr;
208113f74950SBarry Smith   PetscInt       i;
2082905e6a2fSBarry Smith 
20833a40ed3dSBarry Smith   PetscFunctionBegin;
2084905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2085df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
2086905e6a2fSBarry Smith   }
2087905e6a2fSBarry Smith 
2088905e6a2fSBarry Smith   for (i=0; i<n; i++) {
20897dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2090905e6a2fSBarry Smith   }
20913a40ed3dSBarry Smith   PetscFunctionReturn(0);
2092905e6a2fSBarry Smith }
2093905e6a2fSBarry Smith 
2094e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2095c0aa2d19SHong Zhang {
2096c0aa2d19SHong Zhang   PetscFunctionBegin;
2097c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2098c0aa2d19SHong Zhang }
2099c0aa2d19SHong Zhang 
2100e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2101c0aa2d19SHong Zhang {
2102c0aa2d19SHong Zhang   PetscFunctionBegin;
2103c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2104c0aa2d19SHong Zhang }
2105c0aa2d19SHong Zhang 
2106*a76f77c3SStefano Zampini PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
21074b0e389bSBarry Smith {
21084b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
21096849ba73SBarry Smith   PetscErrorCode    ierr;
2110ca15aa20SStefano Zampini   const PetscScalar *va;
2111ca15aa20SStefano Zampini   PetscScalar       *vb;
2112d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
21133a40ed3dSBarry Smith 
21143a40ed3dSBarry Smith   PetscFunctionBegin;
211533f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
211633f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
2117cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
21183a40ed3dSBarry Smith     PetscFunctionReturn(0);
21193a40ed3dSBarry Smith   }
2120e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
2121ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&va);CHKERRQ(ierr);
2122ca15aa20SStefano Zampini   ierr = MatDenseGetArray(B,&vb);CHKERRQ(ierr);
2123a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
21240dbb7854Svictorle     for (j=0; j<n; j++) {
2125ca15aa20SStefano Zampini       ierr = PetscArraycpy(vb+j*lda2,va+j*lda1,m);CHKERRQ(ierr);
2126a5ce6ee0Svictorle     }
2127a5ce6ee0Svictorle   } else {
2128ca15aa20SStefano Zampini     ierr = PetscArraycpy(vb,va,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2129a5ce6ee0Svictorle   }
2130ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(B,&vb);CHKERRQ(ierr);
2131ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&va);CHKERRQ(ierr);
2132ca15aa20SStefano Zampini   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2133ca15aa20SStefano Zampini   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2134273d9f13SBarry Smith   PetscFunctionReturn(0);
2135273d9f13SBarry Smith }
2136273d9f13SBarry Smith 
2137e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
2138273d9f13SBarry Smith {
2139dfbe8321SBarry Smith   PetscErrorCode ierr;
2140273d9f13SBarry Smith 
2141273d9f13SBarry Smith   PetscFunctionBegin;
214218992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
214318992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
214418992e5dSStefano Zampini   if (!A->preallocated) {
2145f4259b30SLisandro Dalcin     ierr = MatSeqDenseSetPreallocation(A,NULL);CHKERRQ(ierr);
214618992e5dSStefano Zampini   }
21473a40ed3dSBarry Smith   PetscFunctionReturn(0);
21484b0e389bSBarry Smith }
21494b0e389bSBarry Smith 
2150ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2151ba337c44SJed Brown {
2152ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2153ca15aa20SStefano Zampini   PetscScalar    *aa;
2154ca15aa20SStefano Zampini   PetscErrorCode ierr;
2155ba337c44SJed Brown 
2156ba337c44SJed Brown   PetscFunctionBegin;
2157ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2158ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2159ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2160ba337c44SJed Brown   PetscFunctionReturn(0);
2161ba337c44SJed Brown }
2162ba337c44SJed Brown 
2163ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2164ba337c44SJed Brown {
2165ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2166ca15aa20SStefano Zampini   PetscScalar    *aa;
2167ca15aa20SStefano Zampini   PetscErrorCode ierr;
2168ba337c44SJed Brown 
2169ba337c44SJed Brown   PetscFunctionBegin;
2170ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2171ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2172ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2173ba337c44SJed Brown   PetscFunctionReturn(0);
2174ba337c44SJed Brown }
2175ba337c44SJed Brown 
2176ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2177ba337c44SJed Brown {
2178ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2179ca15aa20SStefano Zampini   PetscScalar    *aa;
2180ca15aa20SStefano Zampini   PetscErrorCode ierr;
2181ba337c44SJed Brown 
2182ba337c44SJed Brown   PetscFunctionBegin;
2183ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2184ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
2185ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2186ba337c44SJed Brown   PetscFunctionReturn(0);
2187ba337c44SJed Brown }
2188284134d9SBarry Smith 
2189a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
21904222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2191a9fe9ddaSSatish Balay {
2192ee16a9a1SHong Zhang   PetscErrorCode ierr;
2193d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
21947a3c3d58SStefano Zampini   PetscBool      cisdense;
2195a9fe9ddaSSatish Balay 
2196ee16a9a1SHong Zhang   PetscFunctionBegin;
21974222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
21987a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
21997a3c3d58SStefano Zampini   if (!cisdense) {
22007a3c3d58SStefano Zampini     PetscBool flg;
22017a3c3d58SStefano Zampini 
2202ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
22034222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
22047a3c3d58SStefano Zampini   }
220518992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2206ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2207ee16a9a1SHong Zhang }
2208a9fe9ddaSSatish Balay 
2209a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2210a9fe9ddaSSatish Balay {
22116718818eSStefano Zampini   Mat_SeqDense       *a=(Mat_SeqDense*)A->data,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
22120805154bSBarry Smith   PetscBLASInt       m,n,k;
2213ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2214ca15aa20SStefano Zampini   PetscScalar       *cv;
2215a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2216c2916339SPierre Jolivet   PetscErrorCode    ierr;
2217a9fe9ddaSSatish Balay 
2218a9fe9ddaSSatish Balay   PetscFunctionBegin;
22198208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
22208208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2221c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
222249d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
2223ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
2224ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
22256718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
2226ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
2227ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2228ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
2229ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
22306718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2231a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2232a9fe9ddaSSatish Balay }
2233a9fe9ddaSSatish Balay 
22344222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
223569f65d41SStefano Zampini {
223669f65d41SStefano Zampini   PetscErrorCode ierr;
223769f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
22387a3c3d58SStefano Zampini   PetscBool      cisdense;
223969f65d41SStefano Zampini 
224069f65d41SStefano Zampini   PetscFunctionBegin;
22414222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
22427a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
22437a3c3d58SStefano Zampini   if (!cisdense) {
22447a3c3d58SStefano Zampini     PetscBool flg;
22457a3c3d58SStefano Zampini 
2246ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
22474222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
22487a3c3d58SStefano Zampini   }
224918992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
225069f65d41SStefano Zampini   PetscFunctionReturn(0);
225169f65d41SStefano Zampini }
225269f65d41SStefano Zampini 
225369f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
225469f65d41SStefano Zampini {
225569f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
225669f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
225769f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
22586718818eSStefano Zampini   const PetscScalar *av,*bv;
22596718818eSStefano Zampini   PetscScalar       *cv;
226069f65d41SStefano Zampini   PetscBLASInt      m,n,k;
226169f65d41SStefano Zampini   PetscScalar       _DOne=1.0,_DZero=0.0;
226269f65d41SStefano Zampini   PetscErrorCode    ierr;
226369f65d41SStefano Zampini 
226469f65d41SStefano Zampini   PetscFunctionBegin;
226549d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
226649d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
226769f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
226849d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
22696718818eSStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
22706718818eSStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
22716718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
22726718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
22736718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
22746718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
22756718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2276ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
227769f65d41SStefano Zampini   PetscFunctionReturn(0);
227869f65d41SStefano Zampini }
227969f65d41SStefano Zampini 
22804222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2281a9fe9ddaSSatish Balay {
2282ee16a9a1SHong Zhang   PetscErrorCode ierr;
2283d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
22847a3c3d58SStefano Zampini   PetscBool      cisdense;
2285a9fe9ddaSSatish Balay 
2286ee16a9a1SHong Zhang   PetscFunctionBegin;
22874222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
22887a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
22897a3c3d58SStefano Zampini   if (!cisdense) {
22907a3c3d58SStefano Zampini     PetscBool flg;
22917a3c3d58SStefano Zampini 
2292ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
22934222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
22947a3c3d58SStefano Zampini   }
229518992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2296ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2297ee16a9a1SHong Zhang }
2298a9fe9ddaSSatish Balay 
229975648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2300a9fe9ddaSSatish Balay {
2301a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2302a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
2303a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
23046718818eSStefano Zampini   const PetscScalar *av,*bv;
23056718818eSStefano Zampini   PetscScalar       *cv;
23060805154bSBarry Smith   PetscBLASInt      m,n,k;
2307a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2308c5df96a5SBarry Smith   PetscErrorCode    ierr;
2309a9fe9ddaSSatish Balay 
2310a9fe9ddaSSatish Balay   PetscFunctionBegin;
23118208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
23128208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2313c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
231449d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
23156718818eSStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
23166718818eSStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
23176718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
23186718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
23196718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
23206718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
23216718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2322ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2323a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2324a9fe9ddaSSatish Balay }
2325985db425SBarry Smith 
23264222ddf1SHong Zhang /* ----------------------------------------------- */
23274222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
23284222ddf1SHong Zhang {
23294222ddf1SHong Zhang   PetscFunctionBegin;
23304222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
23314222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
23324222ddf1SHong Zhang   PetscFunctionReturn(0);
23334222ddf1SHong Zhang }
23344222ddf1SHong Zhang 
23354222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
23364222ddf1SHong Zhang {
23374222ddf1SHong Zhang   PetscFunctionBegin;
23384222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
23394222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
23404222ddf1SHong Zhang   PetscFunctionReturn(0);
23414222ddf1SHong Zhang }
23424222ddf1SHong Zhang 
23434222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
23444222ddf1SHong Zhang {
23454222ddf1SHong Zhang   PetscFunctionBegin;
23464222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
23474222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
23484222ddf1SHong Zhang   PetscFunctionReturn(0);
23494222ddf1SHong Zhang }
23504222ddf1SHong Zhang 
23514222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
23524222ddf1SHong Zhang {
23534222ddf1SHong Zhang   PetscErrorCode ierr;
23544222ddf1SHong Zhang   Mat_Product    *product = C->product;
23554222ddf1SHong Zhang 
23564222ddf1SHong Zhang   PetscFunctionBegin;
23574222ddf1SHong Zhang   switch (product->type) {
23584222ddf1SHong Zhang   case MATPRODUCT_AB:
23594222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AB(C);CHKERRQ(ierr);
23604222ddf1SHong Zhang     break;
23614222ddf1SHong Zhang   case MATPRODUCT_AtB:
23624222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AtB(C);CHKERRQ(ierr);
23634222ddf1SHong Zhang     break;
23644222ddf1SHong Zhang   case MATPRODUCT_ABt:
23654222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_ABt(C);CHKERRQ(ierr);
23664222ddf1SHong Zhang     break;
23676718818eSStefano Zampini   default:
23684222ddf1SHong Zhang     break;
23694222ddf1SHong Zhang   }
23704222ddf1SHong Zhang   PetscFunctionReturn(0);
23714222ddf1SHong Zhang }
23724222ddf1SHong Zhang /* ----------------------------------------------- */
23734222ddf1SHong Zhang 
2374e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2375985db425SBarry Smith {
2376985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2377985db425SBarry Smith   PetscErrorCode     ierr;
2378d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2379985db425SBarry Smith   PetscScalar        *x;
2380ca15aa20SStefano Zampini   const PetscScalar *aa;
2381985db425SBarry Smith 
2382985db425SBarry Smith   PetscFunctionBegin;
2383e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2384985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2385985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2386ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2387e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2388985db425SBarry Smith   for (i=0; i<m; i++) {
2389985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2390985db425SBarry Smith     for (j=1; j<n; j++) {
2391ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2392985db425SBarry Smith     }
2393985db425SBarry Smith   }
2394ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2395985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2396985db425SBarry Smith   PetscFunctionReturn(0);
2397985db425SBarry Smith }
2398985db425SBarry Smith 
2399e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2400985db425SBarry Smith {
2401985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2402985db425SBarry Smith   PetscErrorCode    ierr;
2403d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2404985db425SBarry Smith   PetscScalar       *x;
2405985db425SBarry Smith   PetscReal         atmp;
2406ca15aa20SStefano Zampini   const PetscScalar *aa;
2407985db425SBarry Smith 
2408985db425SBarry Smith   PetscFunctionBegin;
2409e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2410985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2411985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2412ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2413e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2414985db425SBarry Smith   for (i=0; i<m; i++) {
24159189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2416985db425SBarry Smith     for (j=1; j<n; j++) {
2417ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2418985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2419985db425SBarry Smith     }
2420985db425SBarry Smith   }
2421ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2422985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2423985db425SBarry Smith   PetscFunctionReturn(0);
2424985db425SBarry Smith }
2425985db425SBarry Smith 
2426e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2427985db425SBarry Smith {
2428985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2429985db425SBarry Smith   PetscErrorCode    ierr;
2430d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2431985db425SBarry Smith   PetscScalar       *x;
2432ca15aa20SStefano Zampini   const PetscScalar *aa;
2433985db425SBarry Smith 
2434985db425SBarry Smith   PetscFunctionBegin;
2435e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2436ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2437985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2438985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2439e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2440985db425SBarry Smith   for (i=0; i<m; i++) {
2441985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2442985db425SBarry Smith     for (j=1; j<n; j++) {
2443ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2444985db425SBarry Smith     }
2445985db425SBarry Smith   }
2446985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2447ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2448985db425SBarry Smith   PetscFunctionReturn(0);
2449985db425SBarry Smith }
2450985db425SBarry Smith 
2451637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
24528d0534beSBarry Smith {
24538d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
24548d0534beSBarry Smith   PetscErrorCode    ierr;
24558d0534beSBarry Smith   PetscScalar       *x;
2456ca15aa20SStefano Zampini   const PetscScalar *aa;
24578d0534beSBarry Smith 
24588d0534beSBarry Smith   PetscFunctionBegin;
2459e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2460ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
24618d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2462ca15aa20SStefano Zampini   ierr = PetscArraycpy(x,aa+col*a->lda,A->rmap->n);CHKERRQ(ierr);
24638d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2464ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
24658d0534beSBarry Smith   PetscFunctionReturn(0);
24668d0534beSBarry Smith }
24678d0534beSBarry Smith 
246852c5f739Sprj- PETSC_INTERN PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
24690716a85fSBarry Smith {
24700716a85fSBarry Smith   PetscErrorCode    ierr;
24710716a85fSBarry Smith   PetscInt          i,j,m,n;
24721683a169SBarry Smith   const PetscScalar *a;
24730716a85fSBarry Smith 
24740716a85fSBarry Smith   PetscFunctionBegin;
24750716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2476580bdb30SBarry Smith   ierr = PetscArrayzero(norms,n);CHKERRQ(ierr);
24771683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&a);CHKERRQ(ierr);
24780716a85fSBarry Smith   if (type == NORM_2) {
24790716a85fSBarry Smith     for (i=0; i<n; i++) {
24800716a85fSBarry Smith       for (j=0; j<m; j++) {
24810716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
24820716a85fSBarry Smith       }
24830716a85fSBarry Smith       a += m;
24840716a85fSBarry Smith     }
24850716a85fSBarry Smith   } else if (type == NORM_1) {
24860716a85fSBarry Smith     for (i=0; i<n; i++) {
24870716a85fSBarry Smith       for (j=0; j<m; j++) {
24880716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
24890716a85fSBarry Smith       }
24900716a85fSBarry Smith       a += m;
24910716a85fSBarry Smith     }
24920716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
24930716a85fSBarry Smith     for (i=0; i<n; i++) {
24940716a85fSBarry Smith       for (j=0; j<m; j++) {
24950716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
24960716a85fSBarry Smith       }
24970716a85fSBarry Smith       a += m;
24980716a85fSBarry Smith     }
2499ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
25001683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&a);CHKERRQ(ierr);
25010716a85fSBarry Smith   if (type == NORM_2) {
25028f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
25030716a85fSBarry Smith   }
25040716a85fSBarry Smith   PetscFunctionReturn(0);
25050716a85fSBarry Smith }
25060716a85fSBarry Smith 
250773a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
250873a71a0fSBarry Smith {
250973a71a0fSBarry Smith   PetscErrorCode ierr;
251073a71a0fSBarry Smith   PetscScalar    *a;
2511637a0070SStefano Zampini   PetscInt       lda,m,n,i,j;
251273a71a0fSBarry Smith 
251373a71a0fSBarry Smith   PetscFunctionBegin;
251473a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
2515637a0070SStefano Zampini   ierr = MatDenseGetLDA(x,&lda);CHKERRQ(ierr);
25168c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
2517637a0070SStefano Zampini   for (j=0; j<n; j++) {
2518637a0070SStefano Zampini     for (i=0; i<m; i++) {
2519637a0070SStefano Zampini       ierr = PetscRandomGetValue(rctx,a+j*lda+i);CHKERRQ(ierr);
2520637a0070SStefano Zampini     }
252173a71a0fSBarry Smith   }
25228c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
252373a71a0fSBarry Smith   PetscFunctionReturn(0);
252473a71a0fSBarry Smith }
252573a71a0fSBarry Smith 
25263b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
25273b49f96aSBarry Smith {
25283b49f96aSBarry Smith   PetscFunctionBegin;
25293b49f96aSBarry Smith   *missing = PETSC_FALSE;
25303b49f96aSBarry Smith   PetscFunctionReturn(0);
25313b49f96aSBarry Smith }
253273a71a0fSBarry Smith 
2533ca15aa20SStefano Zampini /* vals is not const */
2534af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
253586aefd0dSHong Zhang {
2536ca15aa20SStefano Zampini   PetscErrorCode ierr;
253786aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2538ca15aa20SStefano Zampini   PetscScalar    *v;
253986aefd0dSHong Zhang 
254086aefd0dSHong Zhang   PetscFunctionBegin;
254186aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2542ca15aa20SStefano Zampini   ierr  = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2543ca15aa20SStefano Zampini   *vals = v+col*a->lda;
2544ca15aa20SStefano Zampini   ierr  = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
254586aefd0dSHong Zhang   PetscFunctionReturn(0);
254686aefd0dSHong Zhang }
254786aefd0dSHong Zhang 
2548af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
254986aefd0dSHong Zhang {
255086aefd0dSHong Zhang   PetscFunctionBegin;
2551f4259b30SLisandro Dalcin   *vals = NULL; /* user cannot accidently use the array later */
255286aefd0dSHong Zhang   PetscFunctionReturn(0);
255386aefd0dSHong Zhang }
2554abc3b08eSStefano Zampini 
2555289bc588SBarry Smith /* -------------------------------------------------------------------*/
2556a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2557905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2558905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2559905e6a2fSBarry Smith                                         MatMult_SeqDense,
256097304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
25617c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
25627c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2563f4259b30SLisandro Dalcin                                         NULL,
2564f4259b30SLisandro Dalcin                                         NULL,
2565f4259b30SLisandro Dalcin                                         NULL,
2566f4259b30SLisandro Dalcin                                 /* 10*/ NULL,
2567905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2568905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
256941f059aeSBarry Smith                                         MatSOR_SeqDense,
2570ec8511deSBarry Smith                                         MatTranspose_SeqDense,
257197304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2572905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2573905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2574905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2575905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2576c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2577c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2578905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2579905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2580d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2581f4259b30SLisandro Dalcin                                         NULL,
2582f4259b30SLisandro Dalcin                                         NULL,
2583f4259b30SLisandro Dalcin                                         NULL,
2584f4259b30SLisandro Dalcin                                         NULL,
25854994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2586f4259b30SLisandro Dalcin                                         NULL,
2587f4259b30SLisandro Dalcin                                         NULL,
2588f4259b30SLisandro Dalcin                                         NULL,
2589f4259b30SLisandro Dalcin                                         NULL,
2590d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2591f4259b30SLisandro Dalcin                                         NULL,
2592f4259b30SLisandro Dalcin                                         NULL,
2593f4259b30SLisandro Dalcin                                         NULL,
2594f4259b30SLisandro Dalcin                                         NULL,
2595d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
25967dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2597f4259b30SLisandro Dalcin                                         NULL,
25984b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2599a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2600d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2601a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
26027d68702bSBarry Smith                                         MatShift_Basic,
2603f4259b30SLisandro Dalcin                                         NULL,
26043f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
260573a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2606f4259b30SLisandro Dalcin                                         NULL,
2607f4259b30SLisandro Dalcin                                         NULL,
2608f4259b30SLisandro Dalcin                                         NULL,
2609f4259b30SLisandro Dalcin                                         NULL,
2610f4259b30SLisandro Dalcin                                 /* 54*/ NULL,
2611f4259b30SLisandro Dalcin                                         NULL,
2612f4259b30SLisandro Dalcin                                         NULL,
2613f4259b30SLisandro Dalcin                                         NULL,
2614f4259b30SLisandro Dalcin                                         NULL,
2615f4259b30SLisandro Dalcin                                 /* 59*/ NULL,
2616e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2617e03a110bSBarry Smith                                         MatView_SeqDense,
2618f4259b30SLisandro Dalcin                                         NULL,
2619f4259b30SLisandro Dalcin                                         NULL,
2620f4259b30SLisandro Dalcin                                 /* 64*/ NULL,
2621f4259b30SLisandro Dalcin                                         NULL,
2622f4259b30SLisandro Dalcin                                         NULL,
2623f4259b30SLisandro Dalcin                                         NULL,
2624f4259b30SLisandro Dalcin                                         NULL,
2625d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
2626f4259b30SLisandro Dalcin                                         NULL,
2627f4259b30SLisandro Dalcin                                         NULL,
2628f4259b30SLisandro Dalcin                                         NULL,
2629f4259b30SLisandro Dalcin                                         NULL,
2630f4259b30SLisandro Dalcin                                 /* 74*/ NULL,
2631f4259b30SLisandro Dalcin                                         NULL,
2632f4259b30SLisandro Dalcin                                         NULL,
2633f4259b30SLisandro Dalcin                                         NULL,
2634f4259b30SLisandro Dalcin                                         NULL,
2635f4259b30SLisandro Dalcin                                 /* 79*/ NULL,
2636f4259b30SLisandro Dalcin                                         NULL,
2637f4259b30SLisandro Dalcin                                         NULL,
2638f4259b30SLisandro Dalcin                                         NULL,
26395bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2640637a0070SStefano Zampini                                         MatIsSymmetric_SeqDense,
26411cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2642f4259b30SLisandro Dalcin                                         NULL,
2643f4259b30SLisandro Dalcin                                         NULL,
2644f4259b30SLisandro Dalcin                                         NULL,
2645f4259b30SLisandro Dalcin                                 /* 89*/ NULL,
2646f4259b30SLisandro Dalcin                                         NULL,
2647a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2648f4259b30SLisandro Dalcin                                         NULL,
2649f4259b30SLisandro Dalcin                                         NULL,
2650f4259b30SLisandro Dalcin                                 /* 94*/ NULL,
2651f4259b30SLisandro Dalcin                                         NULL,
2652f4259b30SLisandro Dalcin                                         NULL,
265369f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2654f4259b30SLisandro Dalcin                                         NULL,
26554222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
2656f4259b30SLisandro Dalcin                                         NULL,
2657f4259b30SLisandro Dalcin                                         NULL,
2658ba337c44SJed Brown                                         MatConjugate_SeqDense,
2659f4259b30SLisandro Dalcin                                         NULL,
2660f4259b30SLisandro Dalcin                                 /*104*/ NULL,
2661ba337c44SJed Brown                                         MatRealPart_SeqDense,
2662ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2663f4259b30SLisandro Dalcin                                         NULL,
2664f4259b30SLisandro Dalcin                                         NULL,
2665f4259b30SLisandro Dalcin                                 /*109*/ NULL,
2666f4259b30SLisandro Dalcin                                         NULL,
26678d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2668aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
26693b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2670f4259b30SLisandro Dalcin                                 /*114*/ NULL,
2671f4259b30SLisandro Dalcin                                         NULL,
2672f4259b30SLisandro Dalcin                                         NULL,
2673f4259b30SLisandro Dalcin                                         NULL,
2674f4259b30SLisandro Dalcin                                         NULL,
2675f4259b30SLisandro Dalcin                                 /*119*/ NULL,
2676f4259b30SLisandro Dalcin                                         NULL,
2677f4259b30SLisandro Dalcin                                         NULL,
2678f4259b30SLisandro Dalcin                                         NULL,
2679f4259b30SLisandro Dalcin                                         NULL,
2680f4259b30SLisandro Dalcin                                 /*124*/ NULL,
26815df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
2682f4259b30SLisandro Dalcin                                         NULL,
2683f4259b30SLisandro Dalcin                                         NULL,
2684f4259b30SLisandro Dalcin                                         NULL,
2685f4259b30SLisandro Dalcin                                 /*129*/ NULL,
2686f4259b30SLisandro Dalcin                                         NULL,
2687f4259b30SLisandro Dalcin                                         NULL,
268875648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
2689f4259b30SLisandro Dalcin                                         NULL,
2690f4259b30SLisandro Dalcin                                 /*134*/ NULL,
2691f4259b30SLisandro Dalcin                                         NULL,
2692f4259b30SLisandro Dalcin                                         NULL,
2693f4259b30SLisandro Dalcin                                         NULL,
2694f4259b30SLisandro Dalcin                                         NULL,
2695f4259b30SLisandro Dalcin                                 /*139*/ NULL,
2696f4259b30SLisandro Dalcin                                         NULL,
2697f4259b30SLisandro Dalcin                                         NULL,
2698f4259b30SLisandro Dalcin                                         NULL,
2699f4259b30SLisandro Dalcin                                         NULL,
27004222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
2701f4259b30SLisandro Dalcin                                 /*145*/ NULL,
2702f4259b30SLisandro Dalcin                                         NULL,
2703f4259b30SLisandro Dalcin                                         NULL
2704985db425SBarry Smith };
270590ace30eSBarry Smith 
27064b828684SBarry Smith /*@C
2707fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2708d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2709d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2710289bc588SBarry Smith 
2711d083f849SBarry Smith    Collective
2712db81eaa0SLois Curfman McInnes 
271320563c6bSBarry Smith    Input Parameters:
2714db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
27150c775827SLois Curfman McInnes .  m - number of rows
271618f449edSLois Curfman McInnes .  n - number of columns
27170298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2718dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
271920563c6bSBarry Smith 
272020563c6bSBarry Smith    Output Parameter:
272144cd7ae7SLois Curfman McInnes .  A - the matrix
272220563c6bSBarry Smith 
2723b259b22eSLois Curfman McInnes    Notes:
272418f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
272518f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
27260298fd71SBarry Smith    set data=NULL.
272718f449edSLois Curfman McInnes 
2728027ccd11SLois Curfman McInnes    Level: intermediate
2729027ccd11SLois Curfman McInnes 
273069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
273120563c6bSBarry Smith @*/
27327087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2733289bc588SBarry Smith {
2734dfbe8321SBarry Smith   PetscErrorCode ierr;
27353b2fbd54SBarry Smith 
27363a40ed3dSBarry Smith   PetscFunctionBegin;
2737f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2738f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2739273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2740273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2741273d9f13SBarry Smith   PetscFunctionReturn(0);
2742273d9f13SBarry Smith }
2743273d9f13SBarry Smith 
2744273d9f13SBarry Smith /*@C
2745273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2746273d9f13SBarry Smith 
2747d083f849SBarry Smith    Collective
2748273d9f13SBarry Smith 
2749273d9f13SBarry Smith    Input Parameters:
27501c4f3114SJed Brown +  B - the matrix
27510298fd71SBarry Smith -  data - the array (or NULL)
2752273d9f13SBarry Smith 
2753273d9f13SBarry Smith    Notes:
2754273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2755273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2756284134d9SBarry Smith    need not call this routine.
2757273d9f13SBarry Smith 
2758273d9f13SBarry Smith    Level: intermediate
2759273d9f13SBarry Smith 
2760ad16ce7aSStefano Zampini .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatDenseSetLDA()
2761867c911aSBarry Smith 
2762273d9f13SBarry Smith @*/
27637087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2764273d9f13SBarry Smith {
27654ac538c5SBarry Smith   PetscErrorCode ierr;
2766a23d5eceSKris Buschelman 
2767a23d5eceSKris Buschelman   PetscFunctionBegin;
2768d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
27694ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2770a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2771a23d5eceSKris Buschelman }
2772a23d5eceSKris Buschelman 
27737087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2774a23d5eceSKris Buschelman {
2775ad16ce7aSStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2776dfbe8321SBarry Smith   PetscErrorCode ierr;
2777273d9f13SBarry Smith 
2778273d9f13SBarry Smith   PetscFunctionBegin;
2779616b8fbbSStefano Zampini   if (b->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
2780273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2781a868139aSShri Abhyankar 
278234ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
278334ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
278434ef9618SShri Abhyankar 
2785ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
278686d161a7SShri Abhyankar 
2787ad16ce7aSStefano Zampini   ierr = PetscIntMultError(b->lda,B->cmap->n,NULL);CHKERRQ(ierr);
27889e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
27899e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2790ad16ce7aSStefano Zampini     ierr = PetscCalloc1((size_t)b->lda*B->cmap->n,&b->v);CHKERRQ(ierr);
2791ad16ce7aSStefano Zampini     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*B->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
27922205254eSKarl Rupp 
27939e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2794273d9f13SBarry Smith   } else { /* user-allocated storage */
27959e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2796273d9f13SBarry Smith     b->v          = data;
2797273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2798273d9f13SBarry Smith   }
27990450473dSBarry Smith   B->assembled = PETSC_TRUE;
2800273d9f13SBarry Smith   PetscFunctionReturn(0);
2801273d9f13SBarry Smith }
2802273d9f13SBarry Smith 
280365b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2804cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
28058baccfbdSHong Zhang {
2806d77f618aSHong Zhang   Mat               mat_elemental;
2807d77f618aSHong Zhang   PetscErrorCode    ierr;
28081683a169SBarry Smith   const PetscScalar *array;
28091683a169SBarry Smith   PetscScalar       *v_colwise;
2810d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2811d77f618aSHong Zhang 
28128baccfbdSHong Zhang   PetscFunctionBegin;
2813d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
28141683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&array);CHKERRQ(ierr);
2815d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2816d77f618aSHong Zhang   k = 0;
2817d77f618aSHong Zhang   for (j=0; j<N; j++) {
2818d77f618aSHong Zhang     cols[j] = j;
2819d77f618aSHong Zhang     for (i=0; i<M; i++) {
2820d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2821d77f618aSHong Zhang     }
2822d77f618aSHong Zhang   }
2823d77f618aSHong Zhang   for (i=0; i<M; i++) {
2824d77f618aSHong Zhang     rows[i] = i;
2825d77f618aSHong Zhang   }
28261683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&array);CHKERRQ(ierr);
2827d77f618aSHong Zhang 
2828d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2829d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2830d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2831d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2832d77f618aSHong Zhang 
2833d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2834d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2835d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2836d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2837d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2838d77f618aSHong Zhang 
2839511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
284028be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2841d77f618aSHong Zhang   } else {
2842d77f618aSHong Zhang     *newmat = mat_elemental;
2843d77f618aSHong Zhang   }
28448baccfbdSHong Zhang   PetscFunctionReturn(0);
28458baccfbdSHong Zhang }
284665b80a83SHong Zhang #endif
28478baccfbdSHong Zhang 
284817359960SJose E. Roman PetscErrorCode  MatDenseSetLDA_SeqDense(Mat B,PetscInt lda)
28491b807ce4Svictorle {
28501b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
28517422da62SJose E. Roman   PetscBool    data;
285221a2c019SBarry Smith 
28531b807ce4Svictorle   PetscFunctionBegin;
28547422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
28557422da62SJose E. Roman   if (!b->user_alloc && data && b->lda!=lda) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"LDA cannot be changed after allocation of internal storage");
2856e32f2f54SBarry Smith   if (lda < B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"LDA %D must be at least matrix dimension %D",lda,B->rmap->n);
28571b807ce4Svictorle   b->lda = lda;
28581b807ce4Svictorle   PetscFunctionReturn(0);
28591b807ce4Svictorle }
28601b807ce4Svictorle 
2861d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
2862d528f656SJakub Kruzik {
2863d528f656SJakub Kruzik   PetscErrorCode ierr;
2864d528f656SJakub Kruzik   PetscMPIInt    size;
2865d528f656SJakub Kruzik 
2866d528f656SJakub Kruzik   PetscFunctionBegin;
2867ffc4695bSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr);
2868d528f656SJakub Kruzik   if (size == 1) {
2869d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
2870d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
2871d528f656SJakub Kruzik     } else {
2872d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2873d528f656SJakub Kruzik     }
2874d528f656SJakub Kruzik   } else {
2875d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
2876d528f656SJakub Kruzik   }
2877d528f656SJakub Kruzik   PetscFunctionReturn(0);
2878d528f656SJakub Kruzik }
2879d528f656SJakub Kruzik 
28806947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
28816947451fSStefano Zampini {
28826947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
28836947451fSStefano Zampini   PetscErrorCode ierr;
28846947451fSStefano Zampini 
28856947451fSStefano Zampini   PetscFunctionBegin;
28865ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
28875ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
28886947451fSStefano Zampini   if (!a->cvec) {
28896947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
2890616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
28916947451fSStefano Zampini   }
28926947451fSStefano Zampini   a->vecinuse = col + 1;
28936947451fSStefano Zampini   ierr = MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
28946947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
28956947451fSStefano Zampini   *v   = a->cvec;
28966947451fSStefano Zampini   PetscFunctionReturn(0);
28976947451fSStefano Zampini }
28986947451fSStefano Zampini 
28996947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
29006947451fSStefano Zampini {
29016947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
29026947451fSStefano Zampini   PetscErrorCode ierr;
29036947451fSStefano Zampini 
29046947451fSStefano Zampini   PetscFunctionBegin;
29055ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
29066947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
29076947451fSStefano Zampini   a->vecinuse = 0;
29086947451fSStefano Zampini   ierr = MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
29096947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
29106947451fSStefano Zampini   *v   = NULL;
29116947451fSStefano Zampini   PetscFunctionReturn(0);
29126947451fSStefano Zampini }
29136947451fSStefano Zampini 
29146947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
29156947451fSStefano Zampini {
29166947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
29176947451fSStefano Zampini   PetscErrorCode ierr;
29186947451fSStefano Zampini 
29196947451fSStefano Zampini   PetscFunctionBegin;
29205ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
29215ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
29226947451fSStefano Zampini   if (!a->cvec) {
29236947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
2924616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
29256947451fSStefano Zampini   }
29266947451fSStefano Zampini   a->vecinuse = col + 1;
29276947451fSStefano Zampini   ierr = MatDenseGetArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
29286947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
29296947451fSStefano Zampini   ierr = VecLockReadPush(a->cvec);CHKERRQ(ierr);
29306947451fSStefano Zampini   *v   = a->cvec;
29316947451fSStefano Zampini   PetscFunctionReturn(0);
29326947451fSStefano Zampini }
29336947451fSStefano Zampini 
29346947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
29356947451fSStefano Zampini {
29366947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
29376947451fSStefano Zampini   PetscErrorCode ierr;
29386947451fSStefano Zampini 
29396947451fSStefano Zampini   PetscFunctionBegin;
29405ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
29416947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
29426947451fSStefano Zampini   a->vecinuse = 0;
29436947451fSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
29446947451fSStefano Zampini   ierr = VecLockReadPop(a->cvec);CHKERRQ(ierr);
29456947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
29466947451fSStefano Zampini   *v   = NULL;
29476947451fSStefano Zampini   PetscFunctionReturn(0);
29486947451fSStefano Zampini }
29496947451fSStefano Zampini 
29506947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
29516947451fSStefano Zampini {
29526947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
29536947451fSStefano Zampini   PetscErrorCode ierr;
29546947451fSStefano Zampini 
29556947451fSStefano Zampini   PetscFunctionBegin;
29565ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
29575ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
29586947451fSStefano Zampini   if (!a->cvec) {
29596947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
2960616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec);CHKERRQ(ierr);
29616947451fSStefano Zampini   }
29626947451fSStefano Zampini   a->vecinuse = col + 1;
29636947451fSStefano Zampini   ierr = MatDenseGetArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
29646947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
29656947451fSStefano Zampini   *v   = a->cvec;
29666947451fSStefano Zampini   PetscFunctionReturn(0);
29676947451fSStefano Zampini }
29686947451fSStefano Zampini 
29696947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
29706947451fSStefano Zampini {
29716947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
29726947451fSStefano Zampini   PetscErrorCode ierr;
29736947451fSStefano Zampini 
29746947451fSStefano Zampini   PetscFunctionBegin;
29755ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
29766947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
29776947451fSStefano Zampini   a->vecinuse = 0;
29786947451fSStefano Zampini   ierr = MatDenseRestoreArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
29796947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
29806947451fSStefano Zampini   *v   = NULL;
29816947451fSStefano Zampini   PetscFunctionReturn(0);
29826947451fSStefano Zampini }
29836947451fSStefano Zampini 
29845ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
29855ea7661aSPierre Jolivet {
29865ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
29875ea7661aSPierre Jolivet   PetscErrorCode ierr;
29885ea7661aSPierre Jolivet 
29895ea7661aSPierre Jolivet   PetscFunctionBegin;
29905ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
29915ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
29925ea7661aSPierre Jolivet   if (a->cmat && cend-cbegin != a->cmat->cmap->N) {
29935ea7661aSPierre Jolivet     ierr = MatDestroy(&a->cmat);CHKERRQ(ierr);
29945ea7661aSPierre Jolivet   }
29955ea7661aSPierre Jolivet   if (!a->cmat) {
2996616b8fbbSStefano Zampini     ierr = MatCreateDense(PetscObjectComm((PetscObject)A),A->rmap->n,PETSC_DECIDE,A->rmap->N,cend-cbegin,(PetscScalar*)a->v + (size_t)cbegin * (size_t)a->lda,&a->cmat);CHKERRQ(ierr);
2997616b8fbbSStefano Zampini     ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)a->cmat);CHKERRQ(ierr);
29985ea7661aSPierre Jolivet   } else {
2999616b8fbbSStefano Zampini     ierr = MatDensePlaceArray(a->cmat,a->v + (size_t)cbegin * (size_t)a->lda);CHKERRQ(ierr);
30005ea7661aSPierre Jolivet   }
3001616b8fbbSStefano Zampini   ierr = MatDenseSetLDA(a->cmat,a->lda);CHKERRQ(ierr);
30025ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
30035ea7661aSPierre Jolivet   *v = a->cmat;
30045ea7661aSPierre Jolivet   PetscFunctionReturn(0);
30055ea7661aSPierre Jolivet }
30065ea7661aSPierre Jolivet 
30075ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A,Mat *v)
30085ea7661aSPierre Jolivet {
30095ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
30105ea7661aSPierre Jolivet   PetscErrorCode ierr;
30115ea7661aSPierre Jolivet 
30125ea7661aSPierre Jolivet   PetscFunctionBegin;
30135ea7661aSPierre Jolivet   if (!a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetSubMatrix() first");
30145ea7661aSPierre Jolivet   if (!a->cmat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column matrix");
3015616b8fbbSStefano Zampini   if (*v != a->cmat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not the matrix obtained from MatDenseGetSubMatrix()");
30165ea7661aSPierre Jolivet   a->matinuse = 0;
30175ea7661aSPierre Jolivet   ierr = MatDenseResetArray(a->cmat);CHKERRQ(ierr);
30185ea7661aSPierre Jolivet   *v   = NULL;
30195ea7661aSPierre Jolivet   PetscFunctionReturn(0);
30205ea7661aSPierre Jolivet }
30215ea7661aSPierre Jolivet 
30220bad9183SKris Buschelman /*MC
3023fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
30240bad9183SKris Buschelman 
30250bad9183SKris Buschelman    Options Database Keys:
30260bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
30270bad9183SKris Buschelman 
30280bad9183SKris Buschelman   Level: beginner
30290bad9183SKris Buschelman 
303089665df3SBarry Smith .seealso: MatCreateSeqDense()
303189665df3SBarry Smith 
30320bad9183SKris Buschelman M*/
3033ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
3034273d9f13SBarry Smith {
3035273d9f13SBarry Smith   Mat_SeqDense   *b;
3036dfbe8321SBarry Smith   PetscErrorCode ierr;
30377c334f02SBarry Smith   PetscMPIInt    size;
3038273d9f13SBarry Smith 
3039273d9f13SBarry Smith   PetscFunctionBegin;
3040ffc4695bSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRMPI(ierr);
3041e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
304255659b69SBarry Smith 
3043b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
3044549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
304544cd7ae7SLois Curfman McInnes   B->data = (void*)b;
304618f449edSLois Curfman McInnes 
3047273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
30484e220ebcSLois Curfman McInnes 
304949a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
3050ad16ce7aSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseSetLDA_C",MatDenseSetLDA_SeqDense);CHKERRQ(ierr);
3051bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
30528572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
3053d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
3054d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
3055d5ea218eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseReplaceArray_C",MatDenseReplaceArray_SeqDense);CHKERRQ(ierr);
30568572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
3057715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
30586947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayWrite_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
30596947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayWrite_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
3060bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
30618baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
30628baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
30638baccfbdSHong Zhang #endif
3064d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
3065d24d4204SJose E. Roman   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_scalapack_C",MatConvert_Dense_ScaLAPACK);CHKERRQ(ierr);
3066d24d4204SJose E. Roman #endif
30672bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
30682bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA);CHKERRQ(ierr);
30694222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
30704222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
3071637a0070SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
30722bf066beSStefano Zampini #endif
3073bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
30744222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
30754222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
30764222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
30774222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
307896e6d5c4SRichard Tran Mills 
3079af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
3080af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
30816947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVec_C",MatDenseGetColumnVec_SeqDense);CHKERRQ(ierr);
30826947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVec_C",MatDenseRestoreColumnVec_SeqDense);CHKERRQ(ierr);
30836947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecRead_C",MatDenseGetColumnVecRead_SeqDense);CHKERRQ(ierr);
30846947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecRead_C",MatDenseRestoreColumnVecRead_SeqDense);CHKERRQ(ierr);
30856947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecWrite_C",MatDenseGetColumnVecWrite_SeqDense);CHKERRQ(ierr);
30866947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecWrite_C",MatDenseRestoreColumnVecWrite_SeqDense);CHKERRQ(ierr);
30875ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetSubMatrix_C",MatDenseGetSubMatrix_SeqDense);CHKERRQ(ierr);
30885ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreSubMatrix_C",MatDenseRestoreSubMatrix_SeqDense);CHKERRQ(ierr);
308917667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
30903a40ed3dSBarry Smith   PetscFunctionReturn(0);
3091289bc588SBarry Smith }
309286aefd0dSHong Zhang 
309386aefd0dSHong Zhang /*@C
3094af53bab2SHong 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.
309586aefd0dSHong Zhang 
309686aefd0dSHong Zhang    Not Collective
309786aefd0dSHong Zhang 
30985ea7661aSPierre Jolivet    Input Parameters:
309986aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
310086aefd0dSHong Zhang -  col - column index
310186aefd0dSHong Zhang 
310286aefd0dSHong Zhang    Output Parameter:
310386aefd0dSHong Zhang .  vals - pointer to the data
310486aefd0dSHong Zhang 
310586aefd0dSHong Zhang    Level: intermediate
310686aefd0dSHong Zhang 
310786aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
310886aefd0dSHong Zhang @*/
310986aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
311086aefd0dSHong Zhang {
311186aefd0dSHong Zhang   PetscErrorCode ierr;
311286aefd0dSHong Zhang 
311386aefd0dSHong Zhang   PetscFunctionBegin;
3114d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3115d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3116d5ea218eSStefano Zampini   PetscValidPointer(vals,3);
311786aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
311886aefd0dSHong Zhang   PetscFunctionReturn(0);
311986aefd0dSHong Zhang }
312086aefd0dSHong Zhang 
312186aefd0dSHong Zhang /*@C
312286aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
312386aefd0dSHong Zhang 
312486aefd0dSHong Zhang    Not Collective
312586aefd0dSHong Zhang 
312686aefd0dSHong Zhang    Input Parameter:
312786aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
312886aefd0dSHong Zhang 
312986aefd0dSHong Zhang    Output Parameter:
313086aefd0dSHong Zhang .  vals - pointer to the data
313186aefd0dSHong Zhang 
313286aefd0dSHong Zhang    Level: intermediate
313386aefd0dSHong Zhang 
313486aefd0dSHong Zhang .seealso: MatDenseGetColumn()
313586aefd0dSHong Zhang @*/
313686aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
313786aefd0dSHong Zhang {
313886aefd0dSHong Zhang   PetscErrorCode ierr;
313986aefd0dSHong Zhang 
314086aefd0dSHong Zhang   PetscFunctionBegin;
3141d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3142d5ea218eSStefano Zampini   PetscValidPointer(vals,2);
314386aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
314486aefd0dSHong Zhang   PetscFunctionReturn(0);
314586aefd0dSHong Zhang }
31466947451fSStefano Zampini 
31476947451fSStefano Zampini /*@C
31486947451fSStefano Zampini    MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec.
31496947451fSStefano Zampini 
31506947451fSStefano Zampini    Collective
31516947451fSStefano Zampini 
31525ea7661aSPierre Jolivet    Input Parameters:
31536947451fSStefano Zampini +  mat - the Mat object
31546947451fSStefano Zampini -  col - the column index
31556947451fSStefano Zampini 
31566947451fSStefano Zampini    Output Parameter:
31576947451fSStefano Zampini .  v - the vector
31586947451fSStefano Zampini 
31596947451fSStefano Zampini    Notes:
31606947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed.
31616947451fSStefano Zampini      Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access.
31626947451fSStefano Zampini 
31636947451fSStefano Zampini    Level: intermediate
31646947451fSStefano Zampini 
31656947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
31666947451fSStefano Zampini @*/
31676947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec(Mat A,PetscInt col,Vec *v)
31686947451fSStefano Zampini {
31696947451fSStefano Zampini   PetscErrorCode ierr;
31706947451fSStefano Zampini 
31716947451fSStefano Zampini   PetscFunctionBegin;
31726947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
31736947451fSStefano Zampini   PetscValidType(A,1);
31746947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
31756947451fSStefano Zampini   PetscValidPointer(v,3);
31766947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
31776947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
31786947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
31796947451fSStefano Zampini   PetscFunctionReturn(0);
31806947451fSStefano Zampini }
31816947451fSStefano Zampini 
31826947451fSStefano Zampini /*@C
31836947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
31846947451fSStefano Zampini 
31856947451fSStefano Zampini    Collective
31866947451fSStefano Zampini 
31875ea7661aSPierre Jolivet    Input Parameters:
31886947451fSStefano Zampini +  mat - the Mat object
31896947451fSStefano Zampini .  col - the column index
31906947451fSStefano Zampini -  v - the Vec object
31916947451fSStefano Zampini 
31926947451fSStefano Zampini    Level: intermediate
31936947451fSStefano Zampini 
31946947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
31956947451fSStefano Zampini @*/
31966947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec *v)
31976947451fSStefano Zampini {
31986947451fSStefano Zampini   PetscErrorCode ierr;
31996947451fSStefano Zampini 
32006947451fSStefano Zampini   PetscFunctionBegin;
32016947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
32026947451fSStefano Zampini   PetscValidType(A,1);
32036947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
32046947451fSStefano Zampini   PetscValidPointer(v,3);
32056947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
32066947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
32076947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
32086947451fSStefano Zampini   PetscFunctionReturn(0);
32096947451fSStefano Zampini }
32106947451fSStefano Zampini 
32116947451fSStefano Zampini /*@C
32126947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
32136947451fSStefano Zampini 
32146947451fSStefano Zampini    Collective
32156947451fSStefano Zampini 
32165ea7661aSPierre Jolivet    Input Parameters:
32176947451fSStefano Zampini +  mat - the Mat object
32186947451fSStefano Zampini -  col - the column index
32196947451fSStefano Zampini 
32206947451fSStefano Zampini    Output Parameter:
32216947451fSStefano Zampini .  v - the vector
32226947451fSStefano Zampini 
32236947451fSStefano Zampini    Notes:
32246947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
32256947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
32266947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
32276947451fSStefano Zampini 
32286947451fSStefano Zampini    Level: intermediate
32296947451fSStefano Zampini 
32306947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
32316947451fSStefano Zampini @*/
32326947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec *v)
32336947451fSStefano Zampini {
32346947451fSStefano Zampini   PetscErrorCode ierr;
32356947451fSStefano Zampini 
32366947451fSStefano Zampini   PetscFunctionBegin;
32376947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
32386947451fSStefano Zampini   PetscValidType(A,1);
32396947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
32406947451fSStefano Zampini   PetscValidPointer(v,3);
32416947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
32426947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
32436947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
32446947451fSStefano Zampini   PetscFunctionReturn(0);
32456947451fSStefano Zampini }
32466947451fSStefano Zampini 
32476947451fSStefano Zampini /*@C
32486947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
32496947451fSStefano Zampini 
32506947451fSStefano Zampini    Collective
32516947451fSStefano Zampini 
32525ea7661aSPierre Jolivet    Input Parameters:
32536947451fSStefano Zampini +  mat - the Mat object
32546947451fSStefano Zampini .  col - the column index
32556947451fSStefano Zampini -  v - the Vec object
32566947451fSStefano Zampini 
32576947451fSStefano Zampini    Level: intermediate
32586947451fSStefano Zampini 
32596947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecWrite()
32606947451fSStefano Zampini @*/
32616947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec *v)
32626947451fSStefano Zampini {
32636947451fSStefano Zampini   PetscErrorCode ierr;
32646947451fSStefano Zampini 
32656947451fSStefano Zampini   PetscFunctionBegin;
32666947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
32676947451fSStefano Zampini   PetscValidType(A,1);
32686947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
32696947451fSStefano Zampini   PetscValidPointer(v,3);
32706947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
32716947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
32726947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
32736947451fSStefano Zampini   PetscFunctionReturn(0);
32746947451fSStefano Zampini }
32756947451fSStefano Zampini 
32766947451fSStefano Zampini /*@C
32776947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
32786947451fSStefano Zampini 
32796947451fSStefano Zampini    Collective
32806947451fSStefano Zampini 
32815ea7661aSPierre Jolivet    Input Parameters:
32826947451fSStefano Zampini +  mat - the Mat object
32836947451fSStefano Zampini -  col - the column index
32846947451fSStefano Zampini 
32856947451fSStefano Zampini    Output Parameter:
32866947451fSStefano Zampini .  v - the vector
32876947451fSStefano Zampini 
32886947451fSStefano Zampini    Notes:
32896947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
32906947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
32916947451fSStefano Zampini 
32926947451fSStefano Zampini    Level: intermediate
32936947451fSStefano Zampini 
32946947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
32956947451fSStefano Zampini @*/
32966947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec *v)
32976947451fSStefano Zampini {
32986947451fSStefano Zampini   PetscErrorCode ierr;
32996947451fSStefano Zampini 
33006947451fSStefano Zampini   PetscFunctionBegin;
33016947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
33026947451fSStefano Zampini   PetscValidType(A,1);
33036947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
33046947451fSStefano Zampini   PetscValidPointer(v,3);
33056947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
33066947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
33076947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
33086947451fSStefano Zampini   PetscFunctionReturn(0);
33096947451fSStefano Zampini }
33106947451fSStefano Zampini 
33116947451fSStefano Zampini /*@C
33126947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
33136947451fSStefano Zampini 
33146947451fSStefano Zampini    Collective
33156947451fSStefano Zampini 
33165ea7661aSPierre Jolivet    Input Parameters:
33176947451fSStefano Zampini +  mat - the Mat object
33186947451fSStefano Zampini .  col - the column index
33196947451fSStefano Zampini -  v - the Vec object
33206947451fSStefano Zampini 
33216947451fSStefano Zampini    Level: intermediate
33226947451fSStefano Zampini 
33236947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead()
33246947451fSStefano Zampini @*/
33256947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec *v)
33266947451fSStefano Zampini {
33276947451fSStefano Zampini   PetscErrorCode ierr;
33286947451fSStefano Zampini 
33296947451fSStefano Zampini   PetscFunctionBegin;
33306947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
33316947451fSStefano Zampini   PetscValidType(A,1);
33326947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
33336947451fSStefano Zampini   PetscValidPointer(v,3);
33346947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
33356947451fSStefano Zampini   if (col < 0 || col > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %D, should be in [0,%D)",col,A->cmap->N);
33366947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
33376947451fSStefano Zampini   PetscFunctionReturn(0);
33386947451fSStefano Zampini }
33395ea7661aSPierre Jolivet 
33405ea7661aSPierre Jolivet /*@C
33415ea7661aSPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of columns of a dense matrix, represented as a Mat.
33425ea7661aSPierre Jolivet 
33435ea7661aSPierre Jolivet    Collective
33445ea7661aSPierre Jolivet 
33455ea7661aSPierre Jolivet    Input Parameters:
33465ea7661aSPierre Jolivet +  mat - the Mat object
33475ea7661aSPierre Jolivet .  cbegin - the first index in the block
33485ea7661aSPierre Jolivet -  cend - the last index in the block
33495ea7661aSPierre Jolivet 
33505ea7661aSPierre Jolivet    Output Parameter:
33515ea7661aSPierre Jolivet .  v - the matrix
33525ea7661aSPierre Jolivet 
33535ea7661aSPierre Jolivet    Notes:
33545ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
33555ea7661aSPierre Jolivet 
33565ea7661aSPierre Jolivet    Level: intermediate
33575ea7661aSPierre Jolivet 
33585ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseRestoreSubMatrix()
33595ea7661aSPierre Jolivet @*/
33605ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
33615ea7661aSPierre Jolivet {
33625ea7661aSPierre Jolivet   PetscErrorCode ierr;
33635ea7661aSPierre Jolivet 
33645ea7661aSPierre Jolivet   PetscFunctionBegin;
33655ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
33665ea7661aSPierre Jolivet   PetscValidType(A,1);
33675ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cbegin,2);
33685ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cend,3);
33695ea7661aSPierre Jolivet   PetscValidPointer(v,4);
33705ea7661aSPierre Jolivet   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
33715ea7661aSPierre Jolivet   if (cbegin < 0 || cbegin > A->cmap->N) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid cbegin %D, should be in [0,%D)",cbegin,A->cmap->N);
3372616b8fbbSStefano Zampini   if (cend < cbegin || cend > A->cmap->N) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid cend %D, should be in [%D,%D)",cend,cbegin,A->cmap->N);
33735ea7661aSPierre Jolivet   ierr = PetscUseMethod(A,"MatDenseGetSubMatrix_C",(Mat,PetscInt,PetscInt,Mat*),(A,cbegin,cend,v));CHKERRQ(ierr);
33745ea7661aSPierre Jolivet   PetscFunctionReturn(0);
33755ea7661aSPierre Jolivet }
33765ea7661aSPierre Jolivet 
33775ea7661aSPierre Jolivet /*@C
33785ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
33795ea7661aSPierre Jolivet 
33805ea7661aSPierre Jolivet    Collective
33815ea7661aSPierre Jolivet 
33825ea7661aSPierre Jolivet    Input Parameters:
33835ea7661aSPierre Jolivet +  mat - the Mat object
33845ea7661aSPierre Jolivet -  v - the Mat object
33855ea7661aSPierre Jolivet 
33865ea7661aSPierre Jolivet    Level: intermediate
33875ea7661aSPierre Jolivet 
33885ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseGetSubMatrix()
33895ea7661aSPierre Jolivet @*/
33905ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix(Mat A,Mat *v)
33915ea7661aSPierre Jolivet {
33925ea7661aSPierre Jolivet   PetscErrorCode ierr;
33935ea7661aSPierre Jolivet 
33945ea7661aSPierre Jolivet   PetscFunctionBegin;
33955ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
33965ea7661aSPierre Jolivet   PetscValidType(A,1);
33975ea7661aSPierre Jolivet   PetscValidPointer(v,2);
33985ea7661aSPierre Jolivet   ierr = PetscUseMethod(A,"MatDenseRestoreSubMatrix_C",(Mat,Mat*),(A,v));CHKERRQ(ierr);
33995ea7661aSPierre Jolivet   PetscFunctionReturn(0);
34005ea7661aSPierre Jolivet }
3401