xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 5ea7661a5c6ebfe94618efd9ae12232cbd7a6c1a)
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;
195b49cda9fSStefano Zampini   MatScalar      *av=a->a;
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   }
213b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
214b49cda9fSStefano Zampini     PetscInt j;
215b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
216b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
217b49cda9fSStefano Zampini       aj++;
218b49cda9fSStefano Zampini       av++;
219b49cda9fSStefano Zampini     }
220b49cda9fSStefano Zampini     ai++;
221b49cda9fSStefano Zampini   }
222b49cda9fSStefano Zampini 
223511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
224a13144ffSStefano Zampini     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
225a13144ffSStefano Zampini     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
22628be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
227b49cda9fSStefano Zampini   } else {
228a13144ffSStefano Zampini     if (B) *newmat = B;
229a13144ffSStefano Zampini     ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
230a13144ffSStefano Zampini     ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
231b49cda9fSStefano Zampini   }
232b49cda9fSStefano Zampini   PetscFunctionReturn(0);
233b49cda9fSStefano Zampini }
234b49cda9fSStefano Zampini 
235cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
2366a63e612SBarry Smith {
2376a63e612SBarry Smith   Mat            B;
2386a63e612SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2396a63e612SBarry Smith   PetscErrorCode ierr;
2409399e1b8SMatthew G. Knepley   PetscInt       i, j;
2419399e1b8SMatthew G. Knepley   PetscInt       *rows, *nnz;
2429399e1b8SMatthew G. Knepley   MatScalar      *aa = a->v, *vals;
2436a63e612SBarry Smith 
2446a63e612SBarry Smith   PetscFunctionBegin;
245ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
2466a63e612SBarry Smith   ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr);
2476a63e612SBarry Smith   ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr);
2489399e1b8SMatthew G. Knepley   ierr = PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals);CHKERRQ(ierr);
2499399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2509399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) ++nnz[i];
2516a63e612SBarry Smith     aa += a->lda;
2526a63e612SBarry Smith   }
2539399e1b8SMatthew G. Knepley   ierr = MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz);CHKERRQ(ierr);
2549399e1b8SMatthew G. Knepley   aa = a->v;
2559399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2569399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2579399e1b8SMatthew G. Knepley     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) {rows[numRows] = i; vals[numRows++] = aa[i];}
2589399e1b8SMatthew G. Knepley     ierr = MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr);
2599399e1b8SMatthew G. Knepley     aa  += a->lda;
2609399e1b8SMatthew G. Knepley   }
2619399e1b8SMatthew G. Knepley   ierr = PetscFree3(rows,nnz,vals);CHKERRQ(ierr);
2626a63e612SBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2636a63e612SBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2646a63e612SBarry Smith 
265511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
26628be2f97SBarry Smith     ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr);
2676a63e612SBarry Smith   } else {
2686a63e612SBarry Smith     *newmat = B;
2696a63e612SBarry Smith   }
2706a63e612SBarry Smith   PetscFunctionReturn(0);
2716a63e612SBarry Smith }
2726a63e612SBarry Smith 
273ca15aa20SStefano Zampini PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
2741987afe7SBarry Smith {
2751987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
276ca15aa20SStefano Zampini   const PetscScalar *xv;
277ca15aa20SStefano Zampini   PetscScalar       *yv;
2780805154bSBarry Smith   PetscBLASInt      N,m,ldax,lday,one = 1;
279efee365bSSatish Balay   PetscErrorCode    ierr;
2803a40ed3dSBarry Smith 
2813a40ed3dSBarry Smith   PetscFunctionBegin;
282ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(X,&xv);CHKERRQ(ierr);
283ca15aa20SStefano Zampini   ierr = MatDenseGetArray(Y,&yv);CHKERRQ(ierr);
284c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n*X->cmap->n,&N);CHKERRQ(ierr);
285c5df96a5SBarry Smith   ierr = PetscBLASIntCast(X->rmap->n,&m);CHKERRQ(ierr);
286c5df96a5SBarry Smith   ierr = PetscBLASIntCast(x->lda,&ldax);CHKERRQ(ierr);
287c5df96a5SBarry Smith   ierr = PetscBLASIntCast(y->lda,&lday);CHKERRQ(ierr);
288a5ce6ee0Svictorle   if (ldax>m || lday>m) {
289ca15aa20SStefano Zampini     PetscInt j;
290ca15aa20SStefano Zampini 
291d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
292ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&alpha,xv+j*ldax,&one,yv+j*lday,&one));
293a5ce6ee0Svictorle     }
294a5ce6ee0Svictorle   } else {
295ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&alpha,xv,&one,yv,&one));
296a5ce6ee0Svictorle   }
297ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(X,&xv);CHKERRQ(ierr);
298ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(Y,&yv);CHKERRQ(ierr);
2990450473dSBarry Smith   ierr = PetscLogFlops(PetscMax(2*N-1,0));CHKERRQ(ierr);
3003a40ed3dSBarry Smith   PetscFunctionReturn(0);
3011987afe7SBarry Smith }
3021987afe7SBarry Smith 
303e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
304289bc588SBarry Smith {
305ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n*A->cmap->n;
3063a40ed3dSBarry Smith 
3073a40ed3dSBarry Smith   PetscFunctionBegin;
3084e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
309ca15aa20SStefano Zampini   info->nz_allocated      = N;
310ca15aa20SStefano Zampini   info->nz_used           = N;
311ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
312ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
3134e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3147adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3154e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3164e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3174e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3183a40ed3dSBarry Smith   PetscFunctionReturn(0);
319289bc588SBarry Smith }
320289bc588SBarry Smith 
321637a0070SStefano Zampini PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
32280cd9d93SLois Curfman McInnes {
323273d9f13SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
324ca15aa20SStefano Zampini   PetscScalar    *v;
325efee365bSSatish Balay   PetscErrorCode ierr;
326c5df96a5SBarry Smith   PetscBLASInt   one = 1,j,nz,lda;
32780cd9d93SLois Curfman McInnes 
3283a40ed3dSBarry Smith   PetscFunctionBegin;
329ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
330c5df96a5SBarry Smith   ierr = PetscBLASIntCast(a->lda,&lda);CHKERRQ(ierr);
331d0f46423SBarry Smith   if (lda>A->rmap->n) {
332c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n,&nz);CHKERRQ(ierr);
333d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
334ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v+j*lda,&one));
335a5ce6ee0Svictorle     }
336a5ce6ee0Svictorle   } else {
337c5df96a5SBarry Smith     ierr = PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz);CHKERRQ(ierr);
338ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v,&one));
339a5ce6ee0Svictorle   }
340efee365bSSatish Balay   ierr = PetscLogFlops(nz);CHKERRQ(ierr);
341ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
3423a40ed3dSBarry Smith   PetscFunctionReturn(0);
34380cd9d93SLois Curfman McInnes }
34480cd9d93SLois Curfman McInnes 
345e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3461cbb95d3SBarry Smith {
3471cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
348ca15aa20SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
349ca15aa20SStefano Zampini   const PetscScalar *v;
350ca15aa20SStefano Zampini   PetscErrorCode    ierr;
3511cbb95d3SBarry Smith 
3521cbb95d3SBarry Smith   PetscFunctionBegin;
3531cbb95d3SBarry Smith   *fl = PETSC_FALSE;
354d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
355ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
3561cbb95d3SBarry Smith   for (i=0; i<m; i++) {
357ca15aa20SStefano Zampini     for (j=i; j<m; j++) {
358637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) {
359637a0070SStefano Zampini         goto restore;
3601cbb95d3SBarry Smith       }
3611cbb95d3SBarry Smith     }
362637a0070SStefano Zampini   }
3631cbb95d3SBarry Smith   *fl  = PETSC_TRUE;
364637a0070SStefano Zampini restore:
365637a0070SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
366637a0070SStefano Zampini   PetscFunctionReturn(0);
367637a0070SStefano Zampini }
368637a0070SStefano Zampini 
369637a0070SStefano Zampini static PetscErrorCode MatIsSymmetric_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
370637a0070SStefano Zampini {
371637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
372637a0070SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
373637a0070SStefano Zampini   const PetscScalar *v;
374637a0070SStefano Zampini   PetscErrorCode    ierr;
375637a0070SStefano Zampini 
376637a0070SStefano Zampini   PetscFunctionBegin;
377637a0070SStefano Zampini   *fl = PETSC_FALSE;
378637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
379637a0070SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
380637a0070SStefano Zampini   for (i=0; i<m; i++) {
381637a0070SStefano Zampini     for (j=i; j<m; j++) {
382637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - v[j+i*N]) > rtol) {
383637a0070SStefano Zampini         goto restore;
384637a0070SStefano Zampini       }
385637a0070SStefano Zampini     }
386637a0070SStefano Zampini   }
387637a0070SStefano Zampini   *fl  = PETSC_TRUE;
388637a0070SStefano Zampini restore:
389637a0070SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
3901cbb95d3SBarry Smith   PetscFunctionReturn(0);
3911cbb95d3SBarry Smith }
3921cbb95d3SBarry Smith 
393ca15aa20SStefano Zampini PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
394b24902e0SBarry Smith {
395ca15aa20SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
396b24902e0SBarry Smith   PetscErrorCode ierr;
39723fc5dcaSStefano Zampini   PetscInt       lda = (PetscInt)mat->lda,j,m,nlda = lda;
398b24902e0SBarry Smith 
399b24902e0SBarry Smith   PetscFunctionBegin;
400aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr);
401aa5ea44dSBarry Smith   ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr);
40223fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
40323fc5dcaSStefano Zampini     ierr = MatDenseSetLDA(newi,lda);CHKERRQ(ierr);
40423fc5dcaSStefano Zampini   }
4050298fd71SBarry Smith   ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr);
406b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
407ca15aa20SStefano Zampini     const PetscScalar *av;
408ca15aa20SStefano Zampini     PetscScalar       *v;
409ca15aa20SStefano Zampini 
410ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
411ca15aa20SStefano Zampini     ierr = MatDenseGetArray(newi,&v);CHKERRQ(ierr);
41223fc5dcaSStefano Zampini     ierr = MatDenseGetLDA(newi,&nlda);CHKERRQ(ierr);
413d0f46423SBarry Smith     m    = A->rmap->n;
41423fc5dcaSStefano Zampini     if (lda>m || nlda>m) {
415d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
41623fc5dcaSStefano Zampini         ierr = PetscArraycpy(v+j*nlda,av+j*lda,m);CHKERRQ(ierr);
417b24902e0SBarry Smith       }
418b24902e0SBarry Smith     } else {
419ca15aa20SStefano Zampini       ierr = PetscArraycpy(v,av,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
420b24902e0SBarry Smith     }
421ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(newi,&v);CHKERRQ(ierr);
422ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
423b24902e0SBarry Smith   }
424b24902e0SBarry Smith   PetscFunctionReturn(0);
425b24902e0SBarry Smith }
426b24902e0SBarry Smith 
427ca15aa20SStefano Zampini PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
42802cad45dSBarry Smith {
4296849ba73SBarry Smith   PetscErrorCode ierr;
43002cad45dSBarry Smith 
4313a40ed3dSBarry Smith   PetscFunctionBegin;
432ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr);
433d0f46423SBarry Smith   ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
4345c9eb25fSBarry Smith   ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
435719d5645SBarry Smith   ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr);
436b24902e0SBarry Smith   PetscFunctionReturn(0);
437b24902e0SBarry Smith }
438b24902e0SBarry Smith 
439e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
440289bc588SBarry Smith {
4414482741eSBarry Smith   MatFactorInfo  info;
442a093e273SMatthew Knepley   PetscErrorCode ierr;
4433a40ed3dSBarry Smith 
4443a40ed3dSBarry Smith   PetscFunctionBegin;
445c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
446ca15aa20SStefano Zampini   ierr = (*fact->ops->lufactor)(fact,0,0,&info);CHKERRQ(ierr);
4473a40ed3dSBarry Smith   PetscFunctionReturn(0);
448289bc588SBarry Smith }
4496ee01492SSatish Balay 
450e0877f53SBarry Smith static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy)
451289bc588SBarry Smith {
452c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
4536849ba73SBarry Smith   PetscErrorCode    ierr;
454f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
455f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
456c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
45767e560aaSBarry Smith 
4583a40ed3dSBarry Smith   PetscFunctionBegin;
459c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
460f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
4611ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
462580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
463d5f3da31SBarry Smith   if (A->factortype == MAT_FACTOR_LU) {
46400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4658b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
46600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
467e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
468d5f3da31SBarry Smith   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
469a49dc2a2SStefano Zampini     if (A->spd) {
47000121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
4718b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
47200121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
473e32f2f54SBarry Smith       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
474a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
475a49dc2a2SStefano Zampini     } else if (A->hermitian) {
47600121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
477a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
47800121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
479a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
480a49dc2a2SStefano Zampini #endif
481a49dc2a2SStefano Zampini     } else { /* symmetric case */
48200121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
483a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
48400121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
485a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
486a49dc2a2SStefano Zampini     }
4872205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
488f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
4891ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
490dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
4913a40ed3dSBarry Smith   PetscFunctionReturn(0);
492289bc588SBarry Smith }
4936ee01492SSatish Balay 
494e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X)
49585e2c93fSHong Zhang {
49685e2c93fSHong Zhang   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
49785e2c93fSHong Zhang   PetscErrorCode    ierr;
4981683a169SBarry Smith   const PetscScalar *b;
4991683a169SBarry Smith   PetscScalar       *x;
500efb80c78SLisandro Dalcin   PetscInt          n;
501783b601eSJed Brown   PetscBLASInt      nrhs,info,m;
50285e2c93fSHong Zhang 
50385e2c93fSHong Zhang   PetscFunctionBegin;
504c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
5050298fd71SBarry Smith   ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr);
506c5df96a5SBarry Smith   ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr);
5071683a169SBarry Smith   ierr = MatDenseGetArrayRead(B,&b);CHKERRQ(ierr);
5088c778c55SBarry Smith   ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr);
50985e2c93fSHong Zhang 
510580bdb30SBarry Smith   ierr = PetscArraycpy(x,b,m*nrhs);CHKERRQ(ierr);
51185e2c93fSHong Zhang 
51285e2c93fSHong Zhang   if (A->factortype == MAT_FACTOR_LU) {
51300121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5148b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
51500121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
51685e2c93fSHong Zhang     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
51785e2c93fSHong Zhang   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
518a49dc2a2SStefano Zampini     if (A->spd) {
51900121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5208b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
52100121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
52285e2c93fSHong Zhang       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
523a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
524a49dc2a2SStefano Zampini     } else if (A->hermitian) {
52500121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
526a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
52700121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
528a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
529a49dc2a2SStefano Zampini #endif
530a49dc2a2SStefano Zampini     } else { /* symmetric case */
53100121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
532a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
53300121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
534a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
535a49dc2a2SStefano Zampini     }
5362205254eSKarl Rupp   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
53785e2c93fSHong Zhang 
5381683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(B,&b);CHKERRQ(ierr);
5398c778c55SBarry Smith   ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr);
54085e2c93fSHong Zhang   ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr);
54185e2c93fSHong Zhang   PetscFunctionReturn(0);
54285e2c93fSHong Zhang }
54385e2c93fSHong Zhang 
54400121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
54500121966SStefano Zampini 
546e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
547da3a660dSBarry Smith {
548c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
549dfbe8321SBarry Smith   PetscErrorCode    ierr;
550f1ceaac6SMatthew G. Knepley   const PetscScalar *x;
551f1ceaac6SMatthew G. Knepley   PetscScalar       *y;
552c5df96a5SBarry Smith   PetscBLASInt      one = 1,info,m;
55367e560aaSBarry Smith 
5543a40ed3dSBarry Smith   PetscFunctionBegin;
555c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
556f1ceaac6SMatthew G. Knepley   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
5571ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
558580bdb30SBarry Smith   ierr = PetscArraycpy(y,x,A->rmap->n);CHKERRQ(ierr);
5598208b9aeSStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
56000121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5618b83055fSJed Brown     PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
56200121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
563e32f2f54SBarry Smith     if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve");
5648208b9aeSStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
565a49dc2a2SStefano Zampini     if (A->spd) {
56600121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
56700121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
56800121966SStefano Zampini #endif
56900121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
5708b83055fSJed Brown       PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info));
57100121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
57200121966SStefano Zampini #if defined(PETSC_USE_COMPLEX)
57300121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
57400121966SStefano Zampini #endif
575a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
576a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
577a49dc2a2SStefano Zampini     } else if (A->hermitian) {
57800121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
57900121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
58000121966SStefano Zampini       PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
58100121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
58200121966SStefano Zampini       ierr = MatConjugate_SeqDense(A);CHKERRQ(ierr);
583ae7cfcebSSatish Balay #endif
584a49dc2a2SStefano Zampini     } else { /* symmetric case */
58500121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
586a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info));
58700121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
588a49dc2a2SStefano Zampini       if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
589da3a660dSBarry Smith     }
590a49dc2a2SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
591f1ceaac6SMatthew G. Knepley   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
5921ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
593dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
5943a40ed3dSBarry Smith   PetscFunctionReturn(0);
595da3a660dSBarry Smith }
5966ee01492SSatish Balay 
597db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
598db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
599db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
600ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
601db4efbfdSBarry Smith {
602db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
603db4efbfdSBarry Smith   PetscErrorCode ierr;
604db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
605db4efbfdSBarry Smith 
606db4efbfdSBarry Smith   PetscFunctionBegin;
607c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
608c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
609db4efbfdSBarry Smith   if (!mat->pivots) {
6108208b9aeSStefano Zampini     ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
6113bb1ff40SBarry Smith     ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
612db4efbfdSBarry Smith   }
613db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
6148e57ea43SSatish Balay   ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6158b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
6168e57ea43SSatish Balay   ierr = PetscFPTrapPop();CHKERRQ(ierr);
6178e57ea43SSatish Balay 
618e32f2f54SBarry Smith   if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
619e32f2f54SBarry Smith   if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
6208208b9aeSStefano Zampini 
621db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6228208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
623db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
624d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
625db4efbfdSBarry Smith 
626f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
627f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
628f6224b95SHong Zhang 
629dc0b31edSSatish Balay   ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr);
630db4efbfdSBarry Smith   PetscFunctionReturn(0);
631db4efbfdSBarry Smith }
632db4efbfdSBarry Smith 
633a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
634ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
635db4efbfdSBarry Smith {
636db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
637db4efbfdSBarry Smith   PetscErrorCode ierr;
638c5df96a5SBarry Smith   PetscBLASInt   info,n;
639db4efbfdSBarry Smith 
640db4efbfdSBarry Smith   PetscFunctionBegin;
641c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
642db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
643a49dc2a2SStefano Zampini   if (A->spd) {
64400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
6458b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
64600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
647a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
648a49dc2a2SStefano Zampini   } else if (A->hermitian) {
649a49dc2a2SStefano Zampini     if (!mat->pivots) {
650a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
651a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
652a49dc2a2SStefano Zampini     }
653a49dc2a2SStefano Zampini     if (!mat->fwork) {
654a49dc2a2SStefano Zampini       PetscScalar dummy;
655a49dc2a2SStefano Zampini 
656a49dc2a2SStefano Zampini       mat->lfwork = -1;
65700121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
658a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
65900121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
660a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
661a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
662a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
663a49dc2a2SStefano Zampini     }
66400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
665a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
66600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
667a49dc2a2SStefano Zampini #endif
668a49dc2a2SStefano Zampini   } else { /* symmetric case */
669a49dc2a2SStefano Zampini     if (!mat->pivots) {
670a49dc2a2SStefano Zampini       ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr);
671a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr);
672a49dc2a2SStefano Zampini     }
673a49dc2a2SStefano Zampini     if (!mat->fwork) {
674a49dc2a2SStefano Zampini       PetscScalar dummy;
675a49dc2a2SStefano Zampini 
676a49dc2a2SStefano Zampini       mat->lfwork = -1;
67700121966SStefano Zampini       ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
678a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
67900121966SStefano Zampini       ierr = PetscFPTrapPop();CHKERRQ(ierr);
680a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
681a49dc2a2SStefano Zampini       ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr);
682a49dc2a2SStefano Zampini       ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr);
683a49dc2a2SStefano Zampini     }
68400121966SStefano Zampini     ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
685a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
68600121966SStefano Zampini     ierr = PetscFPTrapPop();CHKERRQ(ierr);
687a49dc2a2SStefano Zampini   }
688e32f2f54SBarry Smith   if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1);
6898208b9aeSStefano Zampini 
690db4efbfdSBarry Smith   A->ops->solve             = MatSolve_SeqDense;
6918208b9aeSStefano Zampini   A->ops->matsolve          = MatMatSolve_SeqDense;
692db4efbfdSBarry Smith   A->ops->solvetranspose    = MatSolveTranspose_SeqDense;
693d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
6942205254eSKarl Rupp 
695f6224b95SHong Zhang   ierr = PetscFree(A->solvertype);CHKERRQ(ierr);
696f6224b95SHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr);
697f6224b95SHong Zhang 
698eb3f19e4SBarry Smith   ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr);
699db4efbfdSBarry Smith   PetscFunctionReturn(0);
700db4efbfdSBarry Smith }
701db4efbfdSBarry Smith 
7020481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
703db4efbfdSBarry Smith {
704db4efbfdSBarry Smith   PetscErrorCode ierr;
705db4efbfdSBarry Smith   MatFactorInfo  info;
706db4efbfdSBarry Smith 
707db4efbfdSBarry Smith   PetscFunctionBegin;
708db4efbfdSBarry Smith   info.fill = 1.0;
7092205254eSKarl Rupp 
710c3ef05f6SHong Zhang   ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr);
711ca15aa20SStefano Zampini   ierr = (*fact->ops->choleskyfactor)(fact,0,&info);CHKERRQ(ierr);
712db4efbfdSBarry Smith   PetscFunctionReturn(0);
713db4efbfdSBarry Smith }
714db4efbfdSBarry Smith 
715ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
716db4efbfdSBarry Smith {
717db4efbfdSBarry Smith   PetscFunctionBegin;
718c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
7191bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
720719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
721bd443b22SStefano Zampini   fact->ops->solve                 = MatSolve_SeqDense;
722bd443b22SStefano Zampini   fact->ops->matsolve              = MatMatSolve_SeqDense;
723bd443b22SStefano Zampini   fact->ops->solvetranspose        = MatSolveTranspose_SeqDense;
724db4efbfdSBarry Smith   PetscFunctionReturn(0);
725db4efbfdSBarry Smith }
726db4efbfdSBarry Smith 
727ca15aa20SStefano Zampini PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
728db4efbfdSBarry Smith {
729db4efbfdSBarry Smith   PetscFunctionBegin;
730b66fe19dSMatthew G Knepley   fact->preallocated           = PETSC_TRUE;
731c3ef05f6SHong Zhang   fact->assembled              = PETSC_TRUE;
732719d5645SBarry Smith   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
733bd443b22SStefano Zampini   fact->ops->solve             = MatSolve_SeqDense;
734bd443b22SStefano Zampini   fact->ops->matsolve          = MatMatSolve_SeqDense;
735bd443b22SStefano Zampini   fact->ops->solvetranspose    = MatSolveTranspose_SeqDense;
736db4efbfdSBarry Smith   PetscFunctionReturn(0);
737db4efbfdSBarry Smith }
738db4efbfdSBarry Smith 
739ca15aa20SStefano Zampini /* uses LAPACK */
740cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
741db4efbfdSBarry Smith {
742db4efbfdSBarry Smith   PetscErrorCode ierr;
743db4efbfdSBarry Smith 
744db4efbfdSBarry Smith   PetscFunctionBegin;
745ce94432eSBarry Smith   ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr);
746db4efbfdSBarry Smith   ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
747ca15aa20SStefano Zampini   ierr = MatSetType(*fact,MATDENSE);CHKERRQ(ierr);
748db4efbfdSBarry Smith   if (ftype == MAT_FACTOR_LU) {
749db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
750db4efbfdSBarry Smith   } else {
751db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
752db4efbfdSBarry Smith   }
753d5f3da31SBarry Smith   (*fact)->factortype = ftype;
75400c67f3bSHong Zhang 
75500c67f3bSHong Zhang   ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr);
75600c67f3bSHong Zhang   ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr);
757db4efbfdSBarry Smith   PetscFunctionReturn(0);
758db4efbfdSBarry Smith }
759db4efbfdSBarry Smith 
760289bc588SBarry Smith /* ------------------------------------------------------------------*/
761e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
762289bc588SBarry Smith {
763c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
764d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
765d9ca1df4SBarry Smith   const PetscScalar *b;
766dfbe8321SBarry Smith   PetscErrorCode    ierr;
767d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
768c5df96a5SBarry Smith   PetscBLASInt      o = 1,bm;
769289bc588SBarry Smith 
7703a40ed3dSBarry Smith   PetscFunctionBegin;
771ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
772c70f7ee4SJunchao Zhang   if (A->offloadmask == PETSC_OFFLOAD_GPU) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
773ca15aa20SStefano Zampini #endif
774422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
775c5df96a5SBarry Smith   ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr);
776289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
7773bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
7782dcb1b2aSMatthew Knepley     ierr = VecSet(xx,zero);CHKERRQ(ierr);
779289bc588SBarry Smith   }
7801ebc52fbSHong Zhang   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
781d9ca1df4SBarry Smith   ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr);
782b965ef7fSBarry Smith   its  = its*lits;
783e32f2f54SBarry 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);
784289bc588SBarry Smith   while (its--) {
785fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
786289bc588SBarry Smith       for (i=0; i<m; i++) {
7873bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
78855a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
789289bc588SBarry Smith       }
790289bc588SBarry Smith     }
791fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
792289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
7933bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
79455a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
795289bc588SBarry Smith       }
796289bc588SBarry Smith     }
797289bc588SBarry Smith   }
798d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr);
7991ebc52fbSHong Zhang   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
8003a40ed3dSBarry Smith   PetscFunctionReturn(0);
801289bc588SBarry Smith }
802289bc588SBarry Smith 
803289bc588SBarry Smith /* -----------------------------------------------------------------*/
804ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
805289bc588SBarry Smith {
806c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
807d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
808d9ca1df4SBarry Smith   PetscScalar       *y;
809dfbe8321SBarry Smith   PetscErrorCode    ierr;
8100805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
811ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
8123a40ed3dSBarry Smith 
8133a40ed3dSBarry Smith   PetscFunctionBegin;
814c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
815c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
816d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8172bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
8185ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8195ac36cfcSBarry Smith     PetscBLASInt i;
8205ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
8215ac36cfcSBarry Smith   } else {
8228b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
8235ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr);
8245ac36cfcSBarry Smith   }
825d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8262bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
8273a40ed3dSBarry Smith   PetscFunctionReturn(0);
828289bc588SBarry Smith }
829800995b7SMatthew Knepley 
830ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
831289bc588SBarry Smith {
832c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
833d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
834dfbe8321SBarry Smith   PetscErrorCode    ierr;
8350805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
836d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
8373a40ed3dSBarry Smith 
8383a40ed3dSBarry Smith   PetscFunctionBegin;
839c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
840c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
841d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8422bf066beSStefano Zampini   ierr = VecGetArrayWrite(yy,&y);CHKERRQ(ierr);
8435ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
8445ac36cfcSBarry Smith     PetscBLASInt i;
8455ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
8465ac36cfcSBarry Smith   } else {
8478b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
8485ac36cfcSBarry Smith     ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr);
8495ac36cfcSBarry Smith   }
850d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8512bf066beSStefano Zampini   ierr = VecRestoreArrayWrite(yy,&y);CHKERRQ(ierr);
8523a40ed3dSBarry Smith   PetscFunctionReturn(0);
853289bc588SBarry Smith }
8546ee01492SSatish Balay 
855ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
856289bc588SBarry Smith {
857c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
858d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
859d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
860dfbe8321SBarry Smith   PetscErrorCode    ierr;
8610805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
8623a40ed3dSBarry Smith 
8633a40ed3dSBarry Smith   PetscFunctionBegin;
864c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
865c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
866d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
867600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
868d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8691ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8708b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
871d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8721ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
873dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8743a40ed3dSBarry Smith   PetscFunctionReturn(0);
875289bc588SBarry Smith }
8766ee01492SSatish Balay 
877ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
878289bc588SBarry Smith {
879c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
880d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
881d9ca1df4SBarry Smith   PetscScalar       *y;
882dfbe8321SBarry Smith   PetscErrorCode    ierr;
8830805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
88487828ca2SBarry Smith   PetscScalar       _DOne=1.0;
8853a40ed3dSBarry Smith 
8863a40ed3dSBarry Smith   PetscFunctionBegin;
887c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr);
888c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr);
889d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
890600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
891d9ca1df4SBarry Smith   ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr);
8921ebc52fbSHong Zhang   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
8938b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
894d9ca1df4SBarry Smith   ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr);
8951ebc52fbSHong Zhang   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
896dc0b31edSSatish Balay   ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr);
8973a40ed3dSBarry Smith   PetscFunctionReturn(0);
898289bc588SBarry Smith }
899289bc588SBarry Smith 
900289bc588SBarry Smith /* -----------------------------------------------------------------*/
901e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
902289bc588SBarry Smith {
903c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
9046849ba73SBarry Smith   PetscErrorCode ierr;
90513f74950SBarry Smith   PetscInt       i;
90667e560aaSBarry Smith 
9073a40ed3dSBarry Smith   PetscFunctionBegin;
908d0f46423SBarry Smith   *ncols = A->cmap->n;
909289bc588SBarry Smith   if (cols) {
910854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr);
911d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
912289bc588SBarry Smith   }
913289bc588SBarry Smith   if (vals) {
914ca15aa20SStefano Zampini     const PetscScalar *v;
915ca15aa20SStefano Zampini 
916ca15aa20SStefano Zampini     ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
917854ce69bSBarry Smith     ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr);
918ca15aa20SStefano Zampini     v   += row;
919d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
920ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
921289bc588SBarry Smith   }
9223a40ed3dSBarry Smith   PetscFunctionReturn(0);
923289bc588SBarry Smith }
9246ee01492SSatish Balay 
925e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
926289bc588SBarry Smith {
927dfbe8321SBarry Smith   PetscErrorCode ierr;
9286e111a19SKarl Rupp 
929606d414cSSatish Balay   PetscFunctionBegin;
930606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
931606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
9323a40ed3dSBarry Smith   PetscFunctionReturn(0);
933289bc588SBarry Smith }
934289bc588SBarry Smith /* ----------------------------------------------------------------*/
935e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
936289bc588SBarry Smith {
937c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
938ca15aa20SStefano Zampini   PetscScalar      *av;
93913f74950SBarry Smith   PetscInt         i,j,idx=0;
940ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
941c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
942ca15aa20SStefano Zampini #endif
943ca15aa20SStefano Zampini   PetscErrorCode   ierr;
944d6dfbf8fSBarry Smith 
9453a40ed3dSBarry Smith   PetscFunctionBegin;
946ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&av);CHKERRQ(ierr);
947289bc588SBarry Smith   if (!mat->roworiented) {
948dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
949289bc588SBarry Smith       for (j=0; j<n; j++) {
950cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
951cf9c20a2SJed 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);
952289bc588SBarry Smith         for (i=0; i<m; i++) {
953cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
954cf9c20a2SJed 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);
955ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
956289bc588SBarry Smith         }
957289bc588SBarry Smith       }
9583a40ed3dSBarry Smith     } else {
959289bc588SBarry Smith       for (j=0; j<n; j++) {
960cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
961cf9c20a2SJed 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);
962289bc588SBarry Smith         for (i=0; i<m; i++) {
963cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
964cf9c20a2SJed 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);
965ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
966289bc588SBarry Smith         }
967289bc588SBarry Smith       }
968289bc588SBarry Smith     }
9693a40ed3dSBarry Smith   } else {
970dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
971e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
972cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
973cf9c20a2SJed 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);
974e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
975cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
976cf9c20a2SJed 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);
977ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
978e8d4e0b9SBarry Smith         }
979e8d4e0b9SBarry Smith       }
9803a40ed3dSBarry Smith     } else {
981289bc588SBarry Smith       for (i=0; i<m; i++) {
982cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
983cf9c20a2SJed 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);
984289bc588SBarry Smith         for (j=0; j<n; j++) {
985cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
986cf9c20a2SJed 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);
987ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
988289bc588SBarry Smith         }
989289bc588SBarry Smith       }
990289bc588SBarry Smith     }
991e8d4e0b9SBarry Smith   }
992ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
993ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
994c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
995c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
996ca15aa20SStefano Zampini #endif
997ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&av);CHKERRQ(ierr);
998ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
999c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1000ca15aa20SStefano Zampini #endif
10013a40ed3dSBarry Smith   PetscFunctionReturn(0);
1002289bc588SBarry Smith }
1003e8d4e0b9SBarry Smith 
1004e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1005ae80bb75SLois Curfman McInnes {
1006ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1007ca15aa20SStefano Zampini   const PetscScalar *vv;
100813f74950SBarry Smith   PetscInt          i,j;
1009ca15aa20SStefano Zampini   PetscErrorCode    ierr;
1010ae80bb75SLois Curfman McInnes 
10113a40ed3dSBarry Smith   PetscFunctionBegin;
1012ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1013ae80bb75SLois Curfman McInnes   /* row-oriented output */
1014ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
101597e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
1016e32f2f54SBarry 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);
1017ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
10186f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
1019e32f2f54SBarry 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);
1020ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1021ae80bb75SLois Curfman McInnes     }
1022ae80bb75SLois Curfman McInnes   }
1023ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
10243a40ed3dSBarry Smith   PetscFunctionReturn(0);
1025ae80bb75SLois Curfman McInnes }
1026ae80bb75SLois Curfman McInnes 
1027289bc588SBarry Smith /* -----------------------------------------------------------------*/
1028289bc588SBarry Smith 
10298491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1030aabbc4fbSShri Abhyankar {
1031aabbc4fbSShri Abhyankar   PetscErrorCode    ierr;
10328491ab44SLisandro Dalcin   PetscBool         skipHeader;
10338491ab44SLisandro Dalcin   PetscViewerFormat format;
10348491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
10358491ab44SLisandro Dalcin   const PetscScalar *v;
10368491ab44SLisandro Dalcin   PetscScalar       *vwork;
1037aabbc4fbSShri Abhyankar 
1038aabbc4fbSShri Abhyankar   PetscFunctionBegin;
10398491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
10408491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
10418491ab44SLisandro Dalcin   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
10428491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1043aabbc4fbSShri Abhyankar 
10448491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
10458491ab44SLisandro Dalcin 
10468491ab44SLisandro Dalcin   /* write matrix header */
10478491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
10488491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
10498491ab44SLisandro Dalcin   if (!skipHeader) {ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr);}
10508491ab44SLisandro Dalcin 
10518491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
10528491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
10538491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
10548491ab44SLisandro Dalcin     /* store row lengths for each row */
10558491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&iwork);CHKERRQ(ierr);
10568491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
10578491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
10588491ab44SLisandro Dalcin     /* store column indices (zero start index) */
10598491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
10608491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
10618491ab44SLisandro Dalcin         iwork[k] = j;
10628491ab44SLisandro Dalcin     ierr = PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
10638491ab44SLisandro Dalcin     ierr = PetscFree(iwork);CHKERRQ(ierr);
10648491ab44SLisandro Dalcin   }
10658491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
10668491ab44SLisandro Dalcin   ierr = PetscMalloc1(m*N,&vwork);CHKERRQ(ierr);
10678491ab44SLisandro Dalcin   ierr = MatDenseGetArrayRead(mat,&v);CHKERRQ(ierr);
10688491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
10698491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
10708491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
10718491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
10728491ab44SLisandro Dalcin   ierr = MatDenseRestoreArrayRead(mat,&v);CHKERRQ(ierr);
10738491ab44SLisandro Dalcin   ierr = PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
10748491ab44SLisandro Dalcin   ierr = PetscFree(vwork);CHKERRQ(ierr);
10758491ab44SLisandro Dalcin   PetscFunctionReturn(0);
10768491ab44SLisandro Dalcin }
10778491ab44SLisandro Dalcin 
10788491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
10798491ab44SLisandro Dalcin {
10808491ab44SLisandro Dalcin   PetscErrorCode ierr;
10818491ab44SLisandro Dalcin   PetscBool      skipHeader;
10828491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
10838491ab44SLisandro Dalcin   PetscInt       rows,cols;
10848491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
10858491ab44SLisandro Dalcin 
10868491ab44SLisandro Dalcin   PetscFunctionBegin;
10878491ab44SLisandro Dalcin   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
10888491ab44SLisandro Dalcin   ierr = PetscViewerBinaryGetSkipHeader(viewer,&skipHeader);CHKERRQ(ierr);
10898491ab44SLisandro Dalcin 
10908491ab44SLisandro Dalcin   if (!skipHeader) {
10918491ab44SLisandro Dalcin     ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr);
10928491ab44SLisandro Dalcin     if (header[0] != MAT_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
10938491ab44SLisandro Dalcin     M = header[1]; N = header[2];
10948491ab44SLisandro Dalcin     if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M);
10958491ab44SLisandro Dalcin     if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N);
10968491ab44SLisandro Dalcin     nz = header[3];
10978491ab44SLisandro Dalcin     if (nz != MATRIX_BINARY_FORMAT_DENSE && nz < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %D in file",nz);
1098aabbc4fbSShri Abhyankar   } else {
10998491ab44SLisandro Dalcin     ierr = MatGetSize(mat,&M,&N);CHKERRQ(ierr);
11008491ab44SLisandro 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");
11018491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1102e6324fbbSBarry Smith   }
1103aabbc4fbSShri Abhyankar 
11048491ab44SLisandro Dalcin   /* setup global sizes if not set */
11058491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
11068491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
11078491ab44SLisandro Dalcin   ierr = MatSetUp(mat);CHKERRQ(ierr);
11088491ab44SLisandro Dalcin   /* check if global sizes are correct */
11098491ab44SLisandro Dalcin   ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr);
11108491ab44SLisandro 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);
1111aabbc4fbSShri Abhyankar 
11128491ab44SLisandro Dalcin   ierr = MatGetSize(mat,NULL,&N);CHKERRQ(ierr);
11138491ab44SLisandro Dalcin   ierr = MatGetLocalSize(mat,&m,NULL);CHKERRQ(ierr);
11148491ab44SLisandro Dalcin   ierr = MatDenseGetArray(mat,&v);CHKERRQ(ierr);
11158491ab44SLisandro Dalcin   ierr = MatDenseGetLDA(mat,&lda);CHKERRQ(ierr);
11168491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
11178491ab44SLisandro Dalcin     PetscInt nnz = m*N;
11188491ab44SLisandro Dalcin     /* read in matrix values */
11198491ab44SLisandro Dalcin     ierr = PetscMalloc1(nnz,&vwork);CHKERRQ(ierr);
11208491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
11218491ab44SLisandro Dalcin     /* store values in column major order */
11228491ab44SLisandro Dalcin     for (j=0; j<N; j++)
11238491ab44SLisandro Dalcin       for (i=0; i<m; i++)
11248491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
11258491ab44SLisandro Dalcin     ierr = PetscFree(vwork);CHKERRQ(ierr);
11268491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
11278491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
11288491ab44SLisandro Dalcin     /* read in row lengths */
11298491ab44SLisandro Dalcin     ierr = PetscMalloc1(m,&rlens);CHKERRQ(ierr);
11308491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
11318491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
11328491ab44SLisandro Dalcin     /* read in column indices and values */
11338491ab44SLisandro Dalcin     ierr = PetscMalloc2(nnz,&icols,nnz,&vwork);CHKERRQ(ierr);
11348491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT);CHKERRQ(ierr);
11358491ab44SLisandro Dalcin     ierr = PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR);CHKERRQ(ierr);
11368491ab44SLisandro Dalcin     /* store values in column major order */
11378491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
11388491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
11398491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
11408491ab44SLisandro Dalcin     ierr = PetscFree(rlens);CHKERRQ(ierr);
11418491ab44SLisandro Dalcin     ierr = PetscFree2(icols,vwork);CHKERRQ(ierr);
1142aabbc4fbSShri Abhyankar   }
11438491ab44SLisandro Dalcin   ierr = MatDenseRestoreArray(mat,&v);CHKERRQ(ierr);
11448491ab44SLisandro Dalcin   ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
11458491ab44SLisandro Dalcin   ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1146aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1147aabbc4fbSShri Abhyankar }
1148aabbc4fbSShri Abhyankar 
1149eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1150eb91f321SVaclav Hapla {
1151eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1152eb91f321SVaclav Hapla   PetscErrorCode ierr;
1153eb91f321SVaclav Hapla 
1154eb91f321SVaclav Hapla   PetscFunctionBegin;
1155eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1156eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1157eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
1158eb91f321SVaclav Hapla   ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1159eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1160eb91f321SVaclav Hapla   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5);CHKERRQ(ierr);
1161eb91f321SVaclav Hapla   if (isbinary) {
11628491ab44SLisandro Dalcin     ierr = MatLoad_Dense_Binary(newMat,viewer);CHKERRQ(ierr);
1163eb91f321SVaclav Hapla   } else if (ishdf5) {
1164eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
1165eb91f321SVaclav Hapla     ierr = MatLoad_Dense_HDF5(newMat,viewer);CHKERRQ(ierr);
1166eb91f321SVaclav Hapla #else
1167eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1168eb91f321SVaclav Hapla #endif
1169eb91f321SVaclav Hapla   } else {
1170eb91f321SVaclav 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);
1171eb91f321SVaclav Hapla   }
1172eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1173eb91f321SVaclav Hapla }
1174eb91f321SVaclav Hapla 
11756849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1176289bc588SBarry Smith {
1177932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
1178dfbe8321SBarry Smith   PetscErrorCode    ierr;
117913f74950SBarry Smith   PetscInt          i,j;
11802dcb1b2aSMatthew Knepley   const char        *name;
1181ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1182f3ef73ceSBarry Smith   PetscViewerFormat format;
11835f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1184ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
11855f481a85SSatish Balay #endif
1186932b0c3eSLois Curfman McInnes 
11873a40ed3dSBarry Smith   PetscFunctionBegin;
1188ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1189b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1190456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
11913a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1192fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
1193d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1194d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1195ca15aa20SStefano Zampini       v    = av + i;
119677431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr);
1197d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1198aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1199329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
120057622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
1201329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
120257622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr);
12036831982aSBarry Smith         }
120480cd9d93SLois Curfman McInnes #else
12056831982aSBarry Smith         if (*v) {
120657622a8eSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr);
12076831982aSBarry Smith         }
120880cd9d93SLois Curfman McInnes #endif
12091b807ce4Svictorle         v += a->lda;
121080cd9d93SLois Curfman McInnes       }
1211b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
121280cd9d93SLois Curfman McInnes     }
1213d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
12143a40ed3dSBarry Smith   } else {
1215d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr);
1216aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
121747989497SBarry Smith     /* determine if matrix has all real values */
1218ca15aa20SStefano Zampini     v = av;
1219d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1220ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
122147989497SBarry Smith     }
122247989497SBarry Smith #endif
1223fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
12243a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
1225d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1226d0f46423SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr);
1227fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
1228ffac6cdbSBarry Smith     }
1229ffac6cdbSBarry Smith 
1230d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1231ca15aa20SStefano Zampini       v = av + i;
1232d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1233aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
123447989497SBarry Smith         if (allreal) {
1235c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr);
123647989497SBarry Smith         } else {
1237c61cd2faSJed Brown           ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr);
123847989497SBarry Smith         }
1239289bc588SBarry Smith #else
1240c61cd2faSJed Brown         ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr);
1241289bc588SBarry Smith #endif
12421b807ce4Svictorle         v += a->lda;
1243289bc588SBarry Smith       }
1244b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
1245289bc588SBarry Smith     }
1246fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
1247b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
1248ffac6cdbSBarry Smith     }
1249d00279f6SBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr);
1250da3a660dSBarry Smith   }
1251ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&av);CHKERRQ(ierr);
1252b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
12533a40ed3dSBarry Smith   PetscFunctionReturn(0);
1254289bc588SBarry Smith }
1255289bc588SBarry Smith 
12569804daf3SBarry Smith #include <petscdraw.h>
1257e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1258f1af5d2fSBarry Smith {
1259f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
12606849ba73SBarry Smith   PetscErrorCode    ierr;
1261383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1262383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1263ca15aa20SStefano Zampini   const PetscScalar *v;
1264b0a32e0cSBarry Smith   PetscViewer       viewer;
1265b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1266f3ef73ceSBarry Smith   PetscViewerFormat format;
1267f1af5d2fSBarry Smith 
1268f1af5d2fSBarry Smith   PetscFunctionBegin;
1269f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
1270b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
1271b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
1272f1af5d2fSBarry Smith 
1273f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
1274ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&v);CHKERRQ(ierr);
1275fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1276383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1277f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1278f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1279383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1280f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1281f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1282f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1283ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1284ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1285ca15aa20SStefano Zampini         else continue;
1286b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1287f1af5d2fSBarry Smith       }
1288f1af5d2fSBarry Smith     }
1289383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1290f1af5d2fSBarry Smith   } else {
1291f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1292f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1293b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1294b05fc000SLisandro Dalcin     PetscDraw popup;
1295b05fc000SLisandro Dalcin 
1296f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1297f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1298f1af5d2fSBarry Smith     }
1299383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
1300b0a32e0cSBarry Smith     ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
130145f3bb6eSLisandro Dalcin     ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr);
1302383922c3SLisandro Dalcin 
1303383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
1304f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1305f1af5d2fSBarry Smith       x_l = j;
1306f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1307f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1308f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1309f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1310b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
1311b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
1312f1af5d2fSBarry Smith       }
1313f1af5d2fSBarry Smith     }
1314383922c3SLisandro Dalcin     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
1315f1af5d2fSBarry Smith   }
1316ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&v);CHKERRQ(ierr);
1317f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1318f1af5d2fSBarry Smith }
1319f1af5d2fSBarry Smith 
1320e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1321f1af5d2fSBarry Smith {
1322b0a32e0cSBarry Smith   PetscDraw      draw;
1323ace3abfcSBarry Smith   PetscBool      isnull;
1324329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1325dfbe8321SBarry Smith   PetscErrorCode ierr;
1326f1af5d2fSBarry Smith 
1327f1af5d2fSBarry Smith   PetscFunctionBegin;
1328b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
1329b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
1330abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1331f1af5d2fSBarry Smith 
1332d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1333f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
1334b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
1335832b7cebSLisandro Dalcin   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
1336b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
13370298fd71SBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr);
1338832b7cebSLisandro Dalcin   ierr = PetscDrawSave(draw);CHKERRQ(ierr);
1339f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1340f1af5d2fSBarry Smith }
1341f1af5d2fSBarry Smith 
1342dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1343932b0c3eSLois Curfman McInnes {
1344dfbe8321SBarry Smith   PetscErrorCode ierr;
1345ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1346932b0c3eSLois Curfman McInnes 
13473a40ed3dSBarry Smith   PetscFunctionBegin;
1348251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1349251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
1350251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
13510f5bd95cSBarry Smith 
1352c45a1595SBarry Smith   if (iascii) {
1353c45a1595SBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
13540f5bd95cSBarry Smith   } else if (isbinary) {
1355637a0070SStefano Zampini     ierr = MatView_Dense_Binary(A,viewer);CHKERRQ(ierr);
1356f1af5d2fSBarry Smith   } else if (isdraw) {
1357f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
1358932b0c3eSLois Curfman McInnes   }
13593a40ed3dSBarry Smith   PetscFunctionReturn(0);
1360932b0c3eSLois Curfman McInnes }
1361289bc588SBarry Smith 
1362637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array)
1363d3042a70SBarry Smith {
1364d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1365d3042a70SBarry Smith 
1366d3042a70SBarry Smith   PetscFunctionBegin;
1367*5ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
1368*5ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1369*5ea7661aSPierre Jolivet   if (a->unplacedarray) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreArray() first");
1370d3042a70SBarry Smith   a->unplacedarray       = a->v;
1371d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1372d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1373637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1374ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1375c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1376ca15aa20SStefano Zampini #endif
1377d3042a70SBarry Smith   PetscFunctionReturn(0);
1378d3042a70SBarry Smith }
1379d3042a70SBarry Smith 
1380d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1381d3042a70SBarry Smith {
1382d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1383d3042a70SBarry Smith 
1384d3042a70SBarry Smith   PetscFunctionBegin;
1385*5ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
1386*5ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1387d3042a70SBarry Smith   a->v             = a->unplacedarray;
1388d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1389d3042a70SBarry Smith   a->unplacedarray = NULL;
1390ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1391c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1392ca15aa20SStefano Zampini #endif
1393d3042a70SBarry Smith   PetscFunctionReturn(0);
1394d3042a70SBarry Smith }
1395d3042a70SBarry Smith 
1396d5ea218eSStefano Zampini static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A,const PetscScalar *array)
1397d5ea218eSStefano Zampini {
1398d5ea218eSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1399d5ea218eSStefano Zampini   PetscErrorCode ierr;
1400d5ea218eSStefano Zampini 
1401d5ea218eSStefano Zampini   PetscFunctionBegin;
1402*5ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
1403*5ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1404d5ea218eSStefano Zampini   if (!a->user_alloc) { ierr = PetscFree(a->v);CHKERRQ(ierr); }
1405d5ea218eSStefano Zampini   a->v           = (PetscScalar*) array;
1406d5ea218eSStefano Zampini   a->user_alloc  = PETSC_FALSE;
1407d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1408d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1409d5ea218eSStefano Zampini #endif
1410d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1411d5ea218eSStefano Zampini }
1412d5ea218eSStefano Zampini 
1413ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1414289bc588SBarry Smith {
1415ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
1416dfbe8321SBarry Smith   PetscErrorCode ierr;
141790f02eecSBarry Smith 
14183a40ed3dSBarry Smith   PetscFunctionBegin;
1419aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1420d0f46423SBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n);
1421a5a9c739SBarry Smith #endif
142205b42c5fSBarry Smith   ierr = PetscFree(l->pivots);CHKERRQ(ierr);
1423a49dc2a2SStefano Zampini   ierr = PetscFree(l->fwork);CHKERRQ(ierr);
1424abc3b08eSStefano Zampini   ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr);
14256857c123SSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
1426637a0070SStefano Zampini   if (!l->unplaced_user_alloc) {ierr = PetscFree(l->unplacedarray);CHKERRQ(ierr);}
1427*5ea7661aSPierre Jolivet   if (l->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
1428*5ea7661aSPierre Jolivet   if (l->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
14296947451fSStefano Zampini   ierr = VecDestroy(&l->cvec);CHKERRQ(ierr);
1430*5ea7661aSPierre Jolivet   ierr = MatDestroy(&l->cmat);CHKERRQ(ierr);
1431bf0cc555SLisandro Dalcin   ierr = PetscFree(mat->data);CHKERRQ(ierr);
1432dbd8c25aSHong Zhang 
1433dbd8c25aSHong Zhang   ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr);
143449a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL);CHKERRQ(ierr);
1435ad16ce7aSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseSetLDA_C",NULL);CHKERRQ(ierr);
1436bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr);
143752c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr);
1438d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL);CHKERRQ(ierr);
1439d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL);CHKERRQ(ierr);
1440d5ea218eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseReplaceArray_C",NULL);CHKERRQ(ierr);
144152c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL);CHKERRQ(ierr);
144252c5f739Sprj-   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL);CHKERRQ(ierr);
14436947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayWrite_C",NULL);CHKERRQ(ierr);
14446947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayWrite_C",NULL);CHKERRQ(ierr);
14458baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr);
14468baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
14478baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr);
14488baccfbdSHong Zhang #endif
14492bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
14502bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL);CHKERRQ(ierr);
14514222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL);CHKERRQ(ierr);
14524222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL);CHKERRQ(ierr);
14532bf066beSStefano Zampini #endif
1454bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr);
14554222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL);CHKERRQ(ierr);
14564222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL);CHKERRQ(ierr);
14574222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL);CHKERRQ(ierr);
14584222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL);CHKERRQ(ierr);
145952c5f739Sprj- 
146086aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL);CHKERRQ(ierr);
146186aefd0dSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL);CHKERRQ(ierr);
14626947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVec_C",NULL);CHKERRQ(ierr);
14636947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVec_C",NULL);CHKERRQ(ierr);
14646947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecRead_C",NULL);CHKERRQ(ierr);
14656947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecRead_C",NULL);CHKERRQ(ierr);
14666947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecWrite_C",NULL);CHKERRQ(ierr);
14676947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecWrite_C",NULL);CHKERRQ(ierr);
1468*5ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetSubMatrix_C",NULL);CHKERRQ(ierr);
1469*5ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreSubMatrix_C",NULL);CHKERRQ(ierr);
14703a40ed3dSBarry Smith   PetscFunctionReturn(0);
1471289bc588SBarry Smith }
1472289bc588SBarry Smith 
1473e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1474289bc588SBarry Smith {
1475c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
14766849ba73SBarry Smith   PetscErrorCode ierr;
147713f74950SBarry Smith   PetscInt       k,j,m,n,M;
147887828ca2SBarry Smith   PetscScalar    *v,tmp;
147948b35521SBarry Smith 
14803a40ed3dSBarry Smith   PetscFunctionBegin;
1481ca15aa20SStefano Zampini   m = A->rmap->n; M = mat->lda; n = A->cmap->n;
14822847e3fdSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX && m == n) { /* in place transpose */
1483ca15aa20SStefano Zampini     ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1484d3e5ee88SLois Curfman McInnes     for (j=0; j<m; j++) {
1485289bc588SBarry Smith       for (k=0; k<j; k++) {
14861b807ce4Svictorle         tmp        = v[j + k*M];
14871b807ce4Svictorle         v[j + k*M] = v[k + j*M];
14881b807ce4Svictorle         v[k + j*M] = tmp;
1489289bc588SBarry Smith       }
1490289bc588SBarry Smith     }
1491ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
14923a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1493d3e5ee88SLois Curfman McInnes     Mat          tmat;
1494ec8511deSBarry Smith     Mat_SeqDense *tmatd;
149587828ca2SBarry Smith     PetscScalar  *v2;
1496af36a384SStefano Zampini     PetscInt     M2;
1497ea709b57SSatish Balay 
14982847e3fdSStefano Zampini     if (reuse != MAT_REUSE_MATRIX) {
1499ce94432eSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr);
1500d0f46423SBarry Smith       ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr);
15017adad957SLisandro Dalcin       ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
15020298fd71SBarry Smith       ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr);
1503ca15aa20SStefano Zampini     } else tmat = *matout;
1504ca15aa20SStefano Zampini 
1505ca15aa20SStefano Zampini     ierr  = MatDenseGetArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
1506ca15aa20SStefano Zampini     ierr  = MatDenseGetArray(tmat,&v2);CHKERRQ(ierr);
1507ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1508ca15aa20SStefano Zampini     M2    = tmatd->lda;
1509d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1510af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1511d3e5ee88SLois Curfman McInnes     }
1512ca15aa20SStefano Zampini     ierr = MatDenseRestoreArray(tmat,&v2);CHKERRQ(ierr);
1513ca15aa20SStefano Zampini     ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&v);CHKERRQ(ierr);
15146d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15156d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
15162847e3fdSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) *matout = tmat;
15172847e3fdSStefano Zampini     else {
15182847e3fdSStefano Zampini       ierr = MatHeaderMerge(A,&tmat);CHKERRQ(ierr);
15192847e3fdSStefano Zampini     }
152048b35521SBarry Smith   }
15213a40ed3dSBarry Smith   PetscFunctionReturn(0);
1522289bc588SBarry Smith }
1523289bc588SBarry Smith 
1524e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1525289bc588SBarry Smith {
1526c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1527c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1528ca15aa20SStefano Zampini   PetscInt          i;
1529ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
1530ca15aa20SStefano Zampini   PetscErrorCode    ierr;
15319ea5d5aeSSatish Balay 
15323a40ed3dSBarry Smith   PetscFunctionBegin;
1533d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1534d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1535ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A1,&v1);CHKERRQ(ierr);
1536ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A2,&v2);CHKERRQ(ierr);
1537ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
1538ca15aa20SStefano Zampini     ierr = PetscArraycmp(v1,v2,A1->rmap->n,flg);CHKERRQ(ierr);
1539ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1540ca15aa20SStefano Zampini     v1 += mat1->lda;
1541ca15aa20SStefano Zampini     v2 += mat2->lda;
15421b807ce4Svictorle   }
1543ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A1,&v1);CHKERRQ(ierr);
1544ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A2,&v2);CHKERRQ(ierr);
154577c4ece6SBarry Smith   *flg = PETSC_TRUE;
15463a40ed3dSBarry Smith   PetscFunctionReturn(0);
1547289bc588SBarry Smith }
1548289bc588SBarry Smith 
1549e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1550289bc588SBarry Smith {
1551c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
155213f74950SBarry Smith   PetscInt          i,n,len;
1553ca15aa20SStefano Zampini   PetscScalar       *x;
1554ca15aa20SStefano Zampini   const PetscScalar *vv;
1555ca15aa20SStefano Zampini   PetscErrorCode    ierr;
155644cd7ae7SLois Curfman McInnes 
15573a40ed3dSBarry Smith   PetscFunctionBegin;
15587a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
15591ebc52fbSHong Zhang   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1560d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
1561ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&vv);CHKERRQ(ierr);
1562e32f2f54SBarry Smith   if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
156344cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1564ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1565289bc588SBarry Smith   }
1566ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&vv);CHKERRQ(ierr);
15671ebc52fbSHong Zhang   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
15683a40ed3dSBarry Smith   PetscFunctionReturn(0);
1569289bc588SBarry Smith }
1570289bc588SBarry Smith 
1571e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1572289bc588SBarry Smith {
1573c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1574f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1575ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1576dfbe8321SBarry Smith   PetscErrorCode    ierr;
1577d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
157855659b69SBarry Smith 
15793a40ed3dSBarry Smith   PetscFunctionBegin;
1580ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&vv);CHKERRQ(ierr);
158128988994SBarry Smith   if (ll) {
15827a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1583f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr);
1584e32f2f54SBarry Smith     if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1585da3a660dSBarry Smith     for (i=0; i<m; i++) {
1586da3a660dSBarry Smith       x = l[i];
1587ca15aa20SStefano Zampini       v = vv + i;
1588b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1589da3a660dSBarry Smith     }
1590f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr);
1591eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1592da3a660dSBarry Smith   }
159328988994SBarry Smith   if (rr) {
15947a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1595f1ceaac6SMatthew G. Knepley     ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr);
1596e32f2f54SBarry Smith     if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1597da3a660dSBarry Smith     for (i=0; i<n; i++) {
1598da3a660dSBarry Smith       x = r[i];
1599ca15aa20SStefano Zampini       v = vv + i*mat->lda;
16002205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1601da3a660dSBarry Smith     }
1602f1ceaac6SMatthew G. Knepley     ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr);
1603eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr);
1604da3a660dSBarry Smith   }
1605ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&vv);CHKERRQ(ierr);
16063a40ed3dSBarry Smith   PetscFunctionReturn(0);
1607289bc588SBarry Smith }
1608289bc588SBarry Smith 
1609ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1610289bc588SBarry Smith {
1611c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1612ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1613329f5518SBarry Smith   PetscReal         sum  = 0.0;
1614d0f46423SBarry Smith   PetscInt          lda  =mat->lda,m=A->rmap->n,i,j;
1615efee365bSSatish Balay   PetscErrorCode    ierr;
161655659b69SBarry Smith 
16173a40ed3dSBarry Smith   PetscFunctionBegin;
1618ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
1619ca15aa20SStefano Zampini   v    = vv;
1620289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1621a5ce6ee0Svictorle     if (lda>m) {
1622d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1623ca15aa20SStefano Zampini         v = vv+j*lda;
1624a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1625a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1626a5ce6ee0Svictorle         }
1627a5ce6ee0Svictorle       }
1628a5ce6ee0Svictorle     } else {
1629570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1630570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
1631570b7f6dSBarry Smith       *nrm = BLASnrm2_(&cnt,v,&one);
1632570b7f6dSBarry Smith     }
1633570b7f6dSBarry Smith #else
1634d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1635329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1636289bc588SBarry Smith       }
1637a5ce6ee0Svictorle     }
16388f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1639570b7f6dSBarry Smith #endif
1640dc0b31edSSatish Balay     ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16413a40ed3dSBarry Smith   } else if (type == NORM_1) {
1642064f8208SBarry Smith     *nrm = 0.0;
1643d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1644ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
1645289bc588SBarry Smith       sum = 0.0;
1646d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
164733a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1648289bc588SBarry Smith       }
1649064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1650289bc588SBarry Smith     }
1651eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
16523a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1653064f8208SBarry Smith     *nrm = 0.0;
1654d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1655ca15aa20SStefano Zampini       v   = vv + j;
1656289bc588SBarry Smith       sum = 0.0;
1657d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
16581b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1659289bc588SBarry Smith       }
1660064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1661289bc588SBarry Smith     }
1662eb3f19e4SBarry Smith     ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr);
1663e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
1664ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv);CHKERRQ(ierr);
16653a40ed3dSBarry Smith   PetscFunctionReturn(0);
1666289bc588SBarry Smith }
1667289bc588SBarry Smith 
1668e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1669289bc588SBarry Smith {
1670c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
167163ba0a88SBarry Smith   PetscErrorCode ierr;
167267e560aaSBarry Smith 
16733a40ed3dSBarry Smith   PetscFunctionBegin;
1674b5a2b587SKris Buschelman   switch (op) {
1675b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
16764e0d8c25SBarry Smith     aij->roworiented = flg;
1677b5a2b587SKris Buschelman     break;
1678512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1679b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
16803971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
16814e0d8c25SBarry Smith   case MAT_NEW_DIAGONALS:
168213fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1683b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1684b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
16850f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
16865021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
1687071fcb05SBarry Smith   case MAT_SORTED_FULL:
16885021d80fSJed Brown     ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr);
16895021d80fSJed Brown     break;
16905021d80fSJed Brown   case MAT_SPD:
169177e54ba9SKris Buschelman   case MAT_SYMMETRIC:
169277e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
16939a4540c5SBarry Smith   case MAT_HERMITIAN:
16949a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
16955021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
169677e54ba9SKris Buschelman     break;
1697b5a2b587SKris Buschelman   default:
1698e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
16993a40ed3dSBarry Smith   }
17003a40ed3dSBarry Smith   PetscFunctionReturn(0);
1701289bc588SBarry Smith }
1702289bc588SBarry Smith 
1703e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A)
17046f0a148fSBarry Smith {
1705ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
17066849ba73SBarry Smith   PetscErrorCode ierr;
1707d0f46423SBarry Smith   PetscInt       lda=l->lda,m=A->rmap->n,j;
1708ca15aa20SStefano Zampini   PetscScalar    *v;
17093a40ed3dSBarry Smith 
17103a40ed3dSBarry Smith   PetscFunctionBegin;
1711ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
1712a5ce6ee0Svictorle   if (lda>m) {
1713d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1714ca15aa20SStefano Zampini       ierr = PetscArrayzero(v+j*lda,m);CHKERRQ(ierr);
1715a5ce6ee0Svictorle     }
1716a5ce6ee0Svictorle   } else {
1717ca15aa20SStefano Zampini     ierr = PetscArrayzero(v,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
1718a5ce6ee0Svictorle   }
1719ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17203a40ed3dSBarry Smith   PetscFunctionReturn(0);
17216f0a148fSBarry Smith }
17226f0a148fSBarry Smith 
1723e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
17246f0a148fSBarry Smith {
172597b48c8fSBarry Smith   PetscErrorCode    ierr;
1726ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
1727b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
1728ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
172997b48c8fSBarry Smith   const PetscScalar *xx;
173055659b69SBarry Smith 
17313a40ed3dSBarry Smith   PetscFunctionBegin;
173276bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1733b9679d65SBarry Smith     for (i=0; i<N; i++) {
1734b9679d65SBarry Smith       if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1735b9679d65SBarry 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);
1736b9679d65SBarry Smith     }
173776bd3646SJed Brown   }
1738ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1739b9679d65SBarry Smith 
174097b48c8fSBarry Smith   /* fix right hand side if needed */
174197b48c8fSBarry Smith   if (x && b) {
174297b48c8fSBarry Smith     ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr);
174397b48c8fSBarry Smith     ierr = VecGetArray(b,&bb);CHKERRQ(ierr);
17442205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
174597b48c8fSBarry Smith     ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr);
174697b48c8fSBarry Smith     ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr);
174797b48c8fSBarry Smith   }
174897b48c8fSBarry Smith 
1749ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&v);CHKERRQ(ierr);
17506f0a148fSBarry Smith   for (i=0; i<N; i++) {
1751ca15aa20SStefano Zampini     slot = v + rows[i];
1752b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
17536f0a148fSBarry Smith   }
1754f4df32b1SMatthew Knepley   if (diag != 0.0) {
1755b9679d65SBarry Smith     if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
17566f0a148fSBarry Smith     for (i=0; i<N; i++) {
1757ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1758f4df32b1SMatthew Knepley       *slot = diag;
17596f0a148fSBarry Smith     }
17606f0a148fSBarry Smith   }
1761ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
17623a40ed3dSBarry Smith   PetscFunctionReturn(0);
17636f0a148fSBarry Smith }
1764557bce09SLois Curfman McInnes 
176549a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
176649a6ff4bSBarry Smith {
176749a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
176849a6ff4bSBarry Smith 
176949a6ff4bSBarry Smith   PetscFunctionBegin;
177049a6ff4bSBarry Smith   *lda = mat->lda;
177149a6ff4bSBarry Smith   PetscFunctionReturn(0);
177249a6ff4bSBarry Smith }
177349a6ff4bSBarry Smith 
1774637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array)
177564e87e97SBarry Smith {
1776c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
17773a40ed3dSBarry Smith 
17783a40ed3dSBarry Smith   PetscFunctionBegin;
177964e87e97SBarry Smith   *array = mat->v;
17803a40ed3dSBarry Smith   PetscFunctionReturn(0);
178164e87e97SBarry Smith }
17820754003eSLois Curfman McInnes 
1783637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array)
1784ff14e315SSatish Balay {
17853a40ed3dSBarry Smith   PetscFunctionBegin;
1786637a0070SStefano Zampini   *array = NULL;
17873a40ed3dSBarry Smith   PetscFunctionReturn(0);
1788ff14e315SSatish Balay }
17890754003eSLois Curfman McInnes 
1790dec5eb66SMatthew G Knepley /*@C
179149a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
179249a6ff4bSBarry Smith 
1793ad16ce7aSStefano Zampini    Not collective
179449a6ff4bSBarry Smith 
179549a6ff4bSBarry Smith    Input Parameter:
179649a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
179749a6ff4bSBarry Smith 
179849a6ff4bSBarry Smith    Output Parameter:
179949a6ff4bSBarry Smith .   lda - the leading dimension
180049a6ff4bSBarry Smith 
180149a6ff4bSBarry Smith    Level: intermediate
180249a6ff4bSBarry Smith 
1803ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseSetLDA()
180449a6ff4bSBarry Smith @*/
180549a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
180649a6ff4bSBarry Smith {
180749a6ff4bSBarry Smith   PetscErrorCode ierr;
180849a6ff4bSBarry Smith 
180949a6ff4bSBarry Smith   PetscFunctionBegin;
1810d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1811d5ea218eSStefano Zampini   PetscValidPointer(lda,2);
181249a6ff4bSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));CHKERRQ(ierr);
181349a6ff4bSBarry Smith   PetscFunctionReturn(0);
181449a6ff4bSBarry Smith }
181549a6ff4bSBarry Smith 
181649a6ff4bSBarry Smith /*@C
1817ad16ce7aSStefano Zampini    MatDenseSetLDA - Sets the leading dimension of the array used by the dense matrix
1818ad16ce7aSStefano Zampini 
1819ad16ce7aSStefano Zampini    Not collective
1820ad16ce7aSStefano Zampini 
1821ad16ce7aSStefano Zampini    Input Parameter:
1822ad16ce7aSStefano Zampini +  mat - a MATSEQDENSE or MATMPIDENSE matrix
1823ad16ce7aSStefano Zampini -  lda - the leading dimension
1824ad16ce7aSStefano Zampini 
1825ad16ce7aSStefano Zampini    Level: intermediate
1826ad16ce7aSStefano Zampini 
1827ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetLDA()
1828ad16ce7aSStefano Zampini @*/
1829ad16ce7aSStefano Zampini PetscErrorCode  MatDenseSetLDA(Mat A,PetscInt lda)
1830ad16ce7aSStefano Zampini {
1831ad16ce7aSStefano Zampini   PetscErrorCode ierr;
1832ad16ce7aSStefano Zampini 
1833ad16ce7aSStefano Zampini   PetscFunctionBegin;
1834ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1835ad16ce7aSStefano Zampini   ierr = PetscTryMethod(A,"MatDenseSetLDA_C",(Mat,PetscInt),(A,lda));CHKERRQ(ierr);
1836ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
1837ad16ce7aSStefano Zampini }
1838ad16ce7aSStefano Zampini 
1839ad16ce7aSStefano Zampini /*@C
18406947451fSStefano Zampini    MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored
184173a71a0fSBarry Smith 
18428572280aSBarry Smith    Logically Collective on Mat
184373a71a0fSBarry Smith 
184473a71a0fSBarry Smith    Input Parameter:
18456947451fSStefano Zampini .  mat - a dense matrix
184673a71a0fSBarry Smith 
184773a71a0fSBarry Smith    Output Parameter:
184873a71a0fSBarry Smith .   array - pointer to the data
184973a71a0fSBarry Smith 
185073a71a0fSBarry Smith    Level: intermediate
185173a71a0fSBarry Smith 
18526947451fSStefano Zampini .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
185373a71a0fSBarry Smith @*/
18548c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
185573a71a0fSBarry Smith {
185673a71a0fSBarry Smith   PetscErrorCode ierr;
185773a71a0fSBarry Smith 
185873a71a0fSBarry Smith   PetscFunctionBegin;
1859d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1860d5ea218eSStefano Zampini   PetscValidPointer(array,2);
18618c778c55SBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
186273a71a0fSBarry Smith   PetscFunctionReturn(0);
186373a71a0fSBarry Smith }
186473a71a0fSBarry Smith 
1865dec5eb66SMatthew G Knepley /*@C
1866579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
186773a71a0fSBarry Smith 
18688572280aSBarry Smith    Logically Collective on Mat
18698572280aSBarry Smith 
18708572280aSBarry Smith    Input Parameters:
18716947451fSStefano Zampini +  mat - a dense matrix
1872a2b725a8SWilliam Gropp -  array - pointer to the data
18738572280aSBarry Smith 
18748572280aSBarry Smith    Level: intermediate
18758572280aSBarry Smith 
18766947451fSStefano Zampini .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
18778572280aSBarry Smith @*/
18788572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
18798572280aSBarry Smith {
18808572280aSBarry Smith   PetscErrorCode ierr;
18818572280aSBarry Smith 
18828572280aSBarry Smith   PetscFunctionBegin;
1883d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1884d5ea218eSStefano Zampini   PetscValidPointer(array,2);
18858572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
18868572280aSBarry Smith   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
1887637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1888637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1889637a0070SStefano Zampini #endif
18908572280aSBarry Smith   PetscFunctionReturn(0);
18918572280aSBarry Smith }
18928572280aSBarry Smith 
18938572280aSBarry Smith /*@C
18946947451fSStefano Zampini    MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored
18958572280aSBarry Smith 
18968572280aSBarry Smith    Not Collective
18978572280aSBarry Smith 
18988572280aSBarry Smith    Input Parameter:
18996947451fSStefano Zampini .  mat - a dense matrix
19008572280aSBarry Smith 
19018572280aSBarry Smith    Output Parameter:
19028572280aSBarry Smith .   array - pointer to the data
19038572280aSBarry Smith 
19048572280aSBarry Smith    Level: intermediate
19058572280aSBarry Smith 
19066947451fSStefano Zampini .seealso: MatDenseRestoreArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
19078572280aSBarry Smith @*/
19088572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
19098572280aSBarry Smith {
19108572280aSBarry Smith   PetscErrorCode ierr;
19118572280aSBarry Smith 
19128572280aSBarry Smith   PetscFunctionBegin;
1913d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1914d5ea218eSStefano Zampini   PetscValidPointer(array,2);
19158572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
19168572280aSBarry Smith   PetscFunctionReturn(0);
19178572280aSBarry Smith }
19188572280aSBarry Smith 
19198572280aSBarry Smith /*@C
19206947451fSStefano Zampini    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead()
19218572280aSBarry Smith 
192273a71a0fSBarry Smith    Not Collective
192373a71a0fSBarry Smith 
192473a71a0fSBarry Smith    Input Parameters:
19256947451fSStefano Zampini +  mat - a dense matrix
1926a2b725a8SWilliam Gropp -  array - pointer to the data
192773a71a0fSBarry Smith 
192873a71a0fSBarry Smith    Level: intermediate
192973a71a0fSBarry Smith 
19306947451fSStefano Zampini .seealso: MatDenseGetArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
193173a71a0fSBarry Smith @*/
19328572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
193373a71a0fSBarry Smith {
193473a71a0fSBarry Smith   PetscErrorCode ierr;
193573a71a0fSBarry Smith 
193673a71a0fSBarry Smith   PetscFunctionBegin;
1937d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1938d5ea218eSStefano Zampini   PetscValidPointer(array,2);
19398572280aSBarry Smith   ierr = PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));CHKERRQ(ierr);
194073a71a0fSBarry Smith   PetscFunctionReturn(0);
194173a71a0fSBarry Smith }
194273a71a0fSBarry Smith 
19436947451fSStefano Zampini /*@C
19446947451fSStefano Zampini    MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored
19456947451fSStefano Zampini 
19466947451fSStefano Zampini    Not Collective
19476947451fSStefano Zampini 
19486947451fSStefano Zampini    Input Parameter:
19496947451fSStefano Zampini .  mat - a dense matrix
19506947451fSStefano Zampini 
19516947451fSStefano Zampini    Output Parameter:
19526947451fSStefano Zampini .   array - pointer to the data
19536947451fSStefano Zampini 
19546947451fSStefano Zampini    Level: intermediate
19556947451fSStefano Zampini 
19566947451fSStefano Zampini .seealso: MatDenseRestoreArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
19576947451fSStefano Zampini @*/
19586947451fSStefano Zampini PetscErrorCode  MatDenseGetArrayWrite(Mat A,PetscScalar **array)
19596947451fSStefano Zampini {
19606947451fSStefano Zampini   PetscErrorCode ierr;
19616947451fSStefano Zampini 
19626947451fSStefano Zampini   PetscFunctionBegin;
1963d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1964d5ea218eSStefano Zampini   PetscValidPointer(array,2);
19656947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
19666947451fSStefano Zampini   PetscFunctionReturn(0);
19676947451fSStefano Zampini }
19686947451fSStefano Zampini 
19696947451fSStefano Zampini /*@C
19706947451fSStefano Zampini    MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite()
19716947451fSStefano Zampini 
19726947451fSStefano Zampini    Not Collective
19736947451fSStefano Zampini 
19746947451fSStefano Zampini    Input Parameters:
19756947451fSStefano Zampini +  mat - a dense matrix
19766947451fSStefano Zampini -  array - pointer to the data
19776947451fSStefano Zampini 
19786947451fSStefano Zampini    Level: intermediate
19796947451fSStefano Zampini 
19806947451fSStefano Zampini .seealso: MatDenseGetArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
19816947451fSStefano Zampini @*/
19826947451fSStefano Zampini PetscErrorCode  MatDenseRestoreArrayWrite(Mat A,PetscScalar **array)
19836947451fSStefano Zampini {
19846947451fSStefano Zampini   PetscErrorCode ierr;
19856947451fSStefano Zampini 
19866947451fSStefano Zampini   PetscFunctionBegin;
1987d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
1988d5ea218eSStefano Zampini   PetscValidPointer(array,2);
19896947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreArrayWrite_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr);
19906947451fSStefano Zampini   ierr = PetscObjectStateIncrease((PetscObject)A);CHKERRQ(ierr);
19916947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
19926947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
19936947451fSStefano Zampini #endif
19946947451fSStefano Zampini   PetscFunctionReturn(0);
19956947451fSStefano Zampini }
19966947451fSStefano Zampini 
19977dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B)
19980754003eSLois Curfman McInnes {
1999c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
20006849ba73SBarry Smith   PetscErrorCode ierr;
2001ca15aa20SStefano Zampini   PetscInt       i,j,nrows,ncols,blda;
20025d0c19d7SBarry Smith   const PetscInt *irow,*icol;
200387828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
20040754003eSLois Curfman McInnes   Mat            newmat;
20050754003eSLois Curfman McInnes 
20063a40ed3dSBarry Smith   PetscFunctionBegin;
200778b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
200878b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
2009e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
2010e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
20110754003eSLois Curfman McInnes 
2012182d2002SSatish Balay   /* Check submatrixcall */
2013182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
201413f74950SBarry Smith     PetscInt n_cols,n_rows;
2015182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
201621a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2017f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
2018c61587bbSBarry Smith       ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
201921a2c019SBarry Smith     }
2020182d2002SSatish Balay     newmat = *B;
2021182d2002SSatish Balay   } else {
20220754003eSLois Curfman McInnes     /* Create and fill new matrix */
2023ce94432eSBarry Smith     ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr);
2024f69a0ea3SMatthew Knepley     ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr);
20257adad957SLisandro Dalcin     ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr);
20260298fd71SBarry Smith     ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr);
2027182d2002SSatish Balay   }
2028182d2002SSatish Balay 
2029182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
2030ca15aa20SStefano Zampini   ierr = MatDenseGetArray(newmat,&bv);CHKERRQ(ierr);
2031ca15aa20SStefano Zampini   ierr = MatDenseGetLDA(newmat,&blda);CHKERRQ(ierr);
2032182d2002SSatish Balay   for (i=0; i<ncols; i++) {
20336de62eeeSBarry Smith     av = v + mat->lda*icol[i];
2034ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
2035ca15aa20SStefano Zampini     bv += blda;
20360754003eSLois Curfman McInnes   }
2037ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(newmat,&bv);CHKERRQ(ierr);
2038182d2002SSatish Balay 
2039182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
20406d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20416d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
20420754003eSLois Curfman McInnes 
20430754003eSLois Curfman McInnes   /* Free work space */
204478b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
204578b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
2046182d2002SSatish Balay   *B   = newmat;
20473a40ed3dSBarry Smith   PetscFunctionReturn(0);
20480754003eSLois Curfman McInnes }
20490754003eSLois Curfman McInnes 
20507dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2051905e6a2fSBarry Smith {
20526849ba73SBarry Smith   PetscErrorCode ierr;
205313f74950SBarry Smith   PetscInt       i;
2054905e6a2fSBarry Smith 
20553a40ed3dSBarry Smith   PetscFunctionBegin;
2056905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
2057df750dc8SHong Zhang     ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr);
2058905e6a2fSBarry Smith   }
2059905e6a2fSBarry Smith 
2060905e6a2fSBarry Smith   for (i=0; i<n; i++) {
20617dae84e0SHong Zhang     ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
2062905e6a2fSBarry Smith   }
20633a40ed3dSBarry Smith   PetscFunctionReturn(0);
2064905e6a2fSBarry Smith }
2065905e6a2fSBarry Smith 
2066e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2067c0aa2d19SHong Zhang {
2068c0aa2d19SHong Zhang   PetscFunctionBegin;
2069c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2070c0aa2d19SHong Zhang }
2071c0aa2d19SHong Zhang 
2072e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2073c0aa2d19SHong Zhang {
2074c0aa2d19SHong Zhang   PetscFunctionBegin;
2075c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2076c0aa2d19SHong Zhang }
2077c0aa2d19SHong Zhang 
2078e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
20794b0e389bSBarry Smith {
20804b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
20816849ba73SBarry Smith   PetscErrorCode    ierr;
2082ca15aa20SStefano Zampini   const PetscScalar *va;
2083ca15aa20SStefano Zampini   PetscScalar       *vb;
2084d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
20853a40ed3dSBarry Smith 
20863a40ed3dSBarry Smith   PetscFunctionBegin;
208733f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
208833f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
2089cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
20903a40ed3dSBarry Smith     PetscFunctionReturn(0);
20913a40ed3dSBarry Smith   }
2092e32f2f54SBarry Smith   if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
2093ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&va);CHKERRQ(ierr);
2094ca15aa20SStefano Zampini   ierr = MatDenseGetArray(B,&vb);CHKERRQ(ierr);
2095a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
20960dbb7854Svictorle     for (j=0; j<n; j++) {
2097ca15aa20SStefano Zampini       ierr = PetscArraycpy(vb+j*lda2,va+j*lda1,m);CHKERRQ(ierr);
2098a5ce6ee0Svictorle     }
2099a5ce6ee0Svictorle   } else {
2100ca15aa20SStefano Zampini     ierr = PetscArraycpy(vb,va,A->rmap->n*A->cmap->n);CHKERRQ(ierr);
2101a5ce6ee0Svictorle   }
2102ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(B,&vb);CHKERRQ(ierr);
2103ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&va);CHKERRQ(ierr);
2104ca15aa20SStefano Zampini   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2105ca15aa20SStefano Zampini   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2106273d9f13SBarry Smith   PetscFunctionReturn(0);
2107273d9f13SBarry Smith }
2108273d9f13SBarry Smith 
2109e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A)
2110273d9f13SBarry Smith {
2111dfbe8321SBarry Smith   PetscErrorCode ierr;
2112273d9f13SBarry Smith 
2113273d9f13SBarry Smith   PetscFunctionBegin;
211418992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
211518992e5dSStefano Zampini   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
211618992e5dSStefano Zampini   if (!A->preallocated) {
2117273d9f13SBarry Smith     ierr = MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
211818992e5dSStefano Zampini   }
21193a40ed3dSBarry Smith   PetscFunctionReturn(0);
21204b0e389bSBarry Smith }
21214b0e389bSBarry Smith 
2122ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2123ba337c44SJed Brown {
2124ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2125ca15aa20SStefano Zampini   PetscScalar    *aa;
2126ca15aa20SStefano Zampini   PetscErrorCode ierr;
2127ba337c44SJed Brown 
2128ba337c44SJed Brown   PetscFunctionBegin;
2129ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2130ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
2131ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2132ba337c44SJed Brown   PetscFunctionReturn(0);
2133ba337c44SJed Brown }
2134ba337c44SJed Brown 
2135ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2136ba337c44SJed Brown {
2137ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2138ca15aa20SStefano Zampini   PetscScalar    *aa;
2139ca15aa20SStefano Zampini   PetscErrorCode ierr;
2140ba337c44SJed Brown 
2141ba337c44SJed Brown   PetscFunctionBegin;
2142ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2143ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
2144ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2145ba337c44SJed Brown   PetscFunctionReturn(0);
2146ba337c44SJed Brown }
2147ba337c44SJed Brown 
2148ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2149ba337c44SJed Brown {
2150ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2151ca15aa20SStefano Zampini   PetscScalar    *aa;
2152ca15aa20SStefano Zampini   PetscErrorCode ierr;
2153ba337c44SJed Brown 
2154ba337c44SJed Brown   PetscFunctionBegin;
2155ca15aa20SStefano Zampini   ierr = MatDenseGetArray(A,&aa);CHKERRQ(ierr);
2156ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
2157ca15aa20SStefano Zampini   ierr = MatDenseRestoreArray(A,&aa);CHKERRQ(ierr);
2158ba337c44SJed Brown   PetscFunctionReturn(0);
2159ba337c44SJed Brown }
2160284134d9SBarry Smith 
2161a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
21624222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2163a9fe9ddaSSatish Balay {
2164ee16a9a1SHong Zhang   PetscErrorCode ierr;
2165d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
21667a3c3d58SStefano Zampini   PetscBool      cisdense;
2167a9fe9ddaSSatish Balay 
2168ee16a9a1SHong Zhang   PetscFunctionBegin;
21694222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
21707a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
21717a3c3d58SStefano Zampini   if (!cisdense) {
21727a3c3d58SStefano Zampini     PetscBool flg;
21737a3c3d58SStefano Zampini 
2174ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
21754222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
21767a3c3d58SStefano Zampini   }
217718992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2178ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2179ee16a9a1SHong Zhang }
2180a9fe9ddaSSatish Balay 
2181a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2182a9fe9ddaSSatish Balay {
21836718818eSStefano Zampini   Mat_SeqDense       *a=(Mat_SeqDense*)A->data,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
21840805154bSBarry Smith   PetscBLASInt       m,n,k;
2185ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2186ca15aa20SStefano Zampini   PetscScalar       *cv;
2187a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2188c2916339SPierre Jolivet   PetscErrorCode    ierr;
2189a9fe9ddaSSatish Balay 
2190a9fe9ddaSSatish Balay   PetscFunctionBegin;
21918208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
21928208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2193c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
219449d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
2195ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
2196ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
21976718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
2198ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
2199ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2200ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
2201ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
22026718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2203a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2204a9fe9ddaSSatish Balay }
2205a9fe9ddaSSatish Balay 
22064222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
220769f65d41SStefano Zampini {
220869f65d41SStefano Zampini   PetscErrorCode ierr;
220969f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
22107a3c3d58SStefano Zampini   PetscBool      cisdense;
221169f65d41SStefano Zampini 
221269f65d41SStefano Zampini   PetscFunctionBegin;
22134222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
22147a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
22157a3c3d58SStefano Zampini   if (!cisdense) {
22167a3c3d58SStefano Zampini     PetscBool flg;
22177a3c3d58SStefano Zampini 
2218ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
22194222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
22207a3c3d58SStefano Zampini   }
222118992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
222269f65d41SStefano Zampini   PetscFunctionReturn(0);
222369f65d41SStefano Zampini }
222469f65d41SStefano Zampini 
222569f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
222669f65d41SStefano Zampini {
222769f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
222869f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
222969f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
22306718818eSStefano Zampini   const PetscScalar *av,*bv;
22316718818eSStefano Zampini   PetscScalar       *cv;
223269f65d41SStefano Zampini   PetscBLASInt      m,n,k;
223369f65d41SStefano Zampini   PetscScalar       _DOne=1.0,_DZero=0.0;
223469f65d41SStefano Zampini   PetscErrorCode    ierr;
223569f65d41SStefano Zampini 
223669f65d41SStefano Zampini   PetscFunctionBegin;
223749d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
223849d0e964SStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
223969f65d41SStefano Zampini   ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr);
224049d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
22416718818eSStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
22426718818eSStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
22436718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
22446718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
22456718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
22466718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
22476718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2248ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
224969f65d41SStefano Zampini   PetscFunctionReturn(0);
225069f65d41SStefano Zampini }
225169f65d41SStefano Zampini 
22524222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2253a9fe9ddaSSatish Balay {
2254ee16a9a1SHong Zhang   PetscErrorCode ierr;
2255d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
22567a3c3d58SStefano Zampini   PetscBool      cisdense;
2257a9fe9ddaSSatish Balay 
2258ee16a9a1SHong Zhang   PetscFunctionBegin;
22594222ddf1SHong Zhang   ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr);
22607a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
22617a3c3d58SStefano Zampini   if (!cisdense) {
22627a3c3d58SStefano Zampini     PetscBool flg;
22637a3c3d58SStefano Zampini 
2264ca15aa20SStefano Zampini     ierr = PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg);CHKERRQ(ierr);
22654222ddf1SHong Zhang     ierr = MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE);CHKERRQ(ierr);
22667a3c3d58SStefano Zampini   }
226718992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
2268ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2269ee16a9a1SHong Zhang }
2270a9fe9ddaSSatish Balay 
227175648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2272a9fe9ddaSSatish Balay {
2273a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2274a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
2275a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
22766718818eSStefano Zampini   const PetscScalar *av,*bv;
22776718818eSStefano Zampini   PetscScalar       *cv;
22780805154bSBarry Smith   PetscBLASInt      m,n,k;
2279a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2280c5df96a5SBarry Smith   PetscErrorCode    ierr;
2281a9fe9ddaSSatish Balay 
2282a9fe9ddaSSatish Balay   PetscFunctionBegin;
22838208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr);
22848208b9aeSStefano Zampini   ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr);
2285c5df96a5SBarry Smith   ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr);
228649d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
22876718818eSStefano Zampini   ierr = MatDenseGetArrayRead(A,&av);CHKERRQ(ierr);
22886718818eSStefano Zampini   ierr = MatDenseGetArrayRead(B,&bv);CHKERRQ(ierr);
22896718818eSStefano Zampini   ierr = MatDenseGetArrayWrite(C,&cv);CHKERRQ(ierr);
22906718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
22916718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&av);CHKERRQ(ierr);
22926718818eSStefano Zampini   ierr = MatDenseRestoreArrayRead(B,&bv);CHKERRQ(ierr);
22936718818eSStefano Zampini   ierr = MatDenseRestoreArrayWrite(C,&cv);CHKERRQ(ierr);
2294ca15aa20SStefano Zampini   ierr = PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1));CHKERRQ(ierr);
2295a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2296a9fe9ddaSSatish Balay }
2297985db425SBarry Smith 
22984222ddf1SHong Zhang /* ----------------------------------------------- */
22994222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
23004222ddf1SHong Zhang {
23014222ddf1SHong Zhang   PetscFunctionBegin;
23024222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
23034222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
23044222ddf1SHong Zhang   PetscFunctionReturn(0);
23054222ddf1SHong Zhang }
23064222ddf1SHong Zhang 
23074222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
23084222ddf1SHong Zhang {
23094222ddf1SHong Zhang   PetscFunctionBegin;
23104222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
23114222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
23124222ddf1SHong Zhang   PetscFunctionReturn(0);
23134222ddf1SHong Zhang }
23144222ddf1SHong Zhang 
23154222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
23164222ddf1SHong Zhang {
23174222ddf1SHong Zhang   PetscFunctionBegin;
23184222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
23194222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
23204222ddf1SHong Zhang   PetscFunctionReturn(0);
23214222ddf1SHong Zhang }
23224222ddf1SHong Zhang 
23234222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
23244222ddf1SHong Zhang {
23254222ddf1SHong Zhang   PetscErrorCode ierr;
23264222ddf1SHong Zhang   Mat_Product    *product = C->product;
23274222ddf1SHong Zhang 
23284222ddf1SHong Zhang   PetscFunctionBegin;
23294222ddf1SHong Zhang   switch (product->type) {
23304222ddf1SHong Zhang   case MATPRODUCT_AB:
23314222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AB(C);CHKERRQ(ierr);
23324222ddf1SHong Zhang     break;
23334222ddf1SHong Zhang   case MATPRODUCT_AtB:
23344222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_AtB(C);CHKERRQ(ierr);
23354222ddf1SHong Zhang     break;
23364222ddf1SHong Zhang   case MATPRODUCT_ABt:
23374222ddf1SHong Zhang     ierr = MatProductSetFromOptions_SeqDense_ABt(C);CHKERRQ(ierr);
23384222ddf1SHong Zhang     break;
23396718818eSStefano Zampini   default:
23404222ddf1SHong Zhang     break;
23414222ddf1SHong Zhang   }
23424222ddf1SHong Zhang   PetscFunctionReturn(0);
23434222ddf1SHong Zhang }
23444222ddf1SHong Zhang /* ----------------------------------------------- */
23454222ddf1SHong Zhang 
2346e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2347985db425SBarry Smith {
2348985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2349985db425SBarry Smith   PetscErrorCode     ierr;
2350d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2351985db425SBarry Smith   PetscScalar        *x;
2352ca15aa20SStefano Zampini   const PetscScalar *aa;
2353985db425SBarry Smith 
2354985db425SBarry Smith   PetscFunctionBegin;
2355e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2356985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2357985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2358ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2359e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2360985db425SBarry Smith   for (i=0; i<m; i++) {
2361985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2362985db425SBarry Smith     for (j=1; j<n; j++) {
2363ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2364985db425SBarry Smith     }
2365985db425SBarry Smith   }
2366ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2367985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2368985db425SBarry Smith   PetscFunctionReturn(0);
2369985db425SBarry Smith }
2370985db425SBarry Smith 
2371e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2372985db425SBarry Smith {
2373985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2374985db425SBarry Smith   PetscErrorCode    ierr;
2375d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2376985db425SBarry Smith   PetscScalar       *x;
2377985db425SBarry Smith   PetscReal         atmp;
2378ca15aa20SStefano Zampini   const PetscScalar *aa;
2379985db425SBarry Smith 
2380985db425SBarry Smith   PetscFunctionBegin;
2381e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2382985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2383985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2384ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2385e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2386985db425SBarry Smith   for (i=0; i<m; i++) {
23879189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2388985db425SBarry Smith     for (j=1; j<n; j++) {
2389ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2390985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2391985db425SBarry Smith     }
2392985db425SBarry Smith   }
2393ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2394985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2395985db425SBarry Smith   PetscFunctionReturn(0);
2396985db425SBarry Smith }
2397985db425SBarry Smith 
2398e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2399985db425SBarry Smith {
2400985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2401985db425SBarry Smith   PetscErrorCode    ierr;
2402d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2403985db425SBarry Smith   PetscScalar       *x;
2404ca15aa20SStefano Zampini   const PetscScalar *aa;
2405985db425SBarry Smith 
2406985db425SBarry Smith   PetscFunctionBegin;
2407e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2408ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
2409985db425SBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2410985db425SBarry Smith   ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr);
2411e32f2f54SBarry Smith   if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2412985db425SBarry Smith   for (i=0; i<m; i++) {
2413985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2414985db425SBarry Smith     for (j=1; j<n; j++) {
2415ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2416985db425SBarry Smith     }
2417985db425SBarry Smith   }
2418985db425SBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2419ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
2420985db425SBarry Smith   PetscFunctionReturn(0);
2421985db425SBarry Smith }
2422985db425SBarry Smith 
2423637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
24248d0534beSBarry Smith {
24258d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
24268d0534beSBarry Smith   PetscErrorCode    ierr;
24278d0534beSBarry Smith   PetscScalar       *x;
2428ca15aa20SStefano Zampini   const PetscScalar *aa;
24298d0534beSBarry Smith 
24308d0534beSBarry Smith   PetscFunctionBegin;
2431e32f2f54SBarry Smith   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2432ca15aa20SStefano Zampini   ierr = MatDenseGetArrayRead(A,&aa);CHKERRQ(ierr);
24338d0534beSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
2434ca15aa20SStefano Zampini   ierr = PetscArraycpy(x,aa+col*a->lda,A->rmap->n);CHKERRQ(ierr);
24358d0534beSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
2436ca15aa20SStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&aa);CHKERRQ(ierr);
24378d0534beSBarry Smith   PetscFunctionReturn(0);
24388d0534beSBarry Smith }
24398d0534beSBarry Smith 
244052c5f739Sprj- PETSC_INTERN PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms)
24410716a85fSBarry Smith {
24420716a85fSBarry Smith   PetscErrorCode    ierr;
24430716a85fSBarry Smith   PetscInt          i,j,m,n;
24441683a169SBarry Smith   const PetscScalar *a;
24450716a85fSBarry Smith 
24460716a85fSBarry Smith   PetscFunctionBegin;
24470716a85fSBarry Smith   ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2448580bdb30SBarry Smith   ierr = PetscArrayzero(norms,n);CHKERRQ(ierr);
24491683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&a);CHKERRQ(ierr);
24500716a85fSBarry Smith   if (type == NORM_2) {
24510716a85fSBarry Smith     for (i=0; i<n; i++) {
24520716a85fSBarry Smith       for (j=0; j<m; j++) {
24530716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]*a[j]);
24540716a85fSBarry Smith       }
24550716a85fSBarry Smith       a += m;
24560716a85fSBarry Smith     }
24570716a85fSBarry Smith   } else if (type == NORM_1) {
24580716a85fSBarry Smith     for (i=0; i<n; i++) {
24590716a85fSBarry Smith       for (j=0; j<m; j++) {
24600716a85fSBarry Smith         norms[i] += PetscAbsScalar(a[j]);
24610716a85fSBarry Smith       }
24620716a85fSBarry Smith       a += m;
24630716a85fSBarry Smith     }
24640716a85fSBarry Smith   } else if (type == NORM_INFINITY) {
24650716a85fSBarry Smith     for (i=0; i<n; i++) {
24660716a85fSBarry Smith       for (j=0; j<m; j++) {
24670716a85fSBarry Smith         norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]);
24680716a85fSBarry Smith       }
24690716a85fSBarry Smith       a += m;
24700716a85fSBarry Smith     }
2471ce94432eSBarry Smith   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType");
24721683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&a);CHKERRQ(ierr);
24730716a85fSBarry Smith   if (type == NORM_2) {
24748f1a2a5eSBarry Smith     for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]);
24750716a85fSBarry Smith   }
24760716a85fSBarry Smith   PetscFunctionReturn(0);
24770716a85fSBarry Smith }
24780716a85fSBarry Smith 
247973a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
248073a71a0fSBarry Smith {
248173a71a0fSBarry Smith   PetscErrorCode ierr;
248273a71a0fSBarry Smith   PetscScalar    *a;
2483637a0070SStefano Zampini   PetscInt       lda,m,n,i,j;
248473a71a0fSBarry Smith 
248573a71a0fSBarry Smith   PetscFunctionBegin;
248673a71a0fSBarry Smith   ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr);
2487637a0070SStefano Zampini   ierr = MatDenseGetLDA(x,&lda);CHKERRQ(ierr);
24888c778c55SBarry Smith   ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr);
2489637a0070SStefano Zampini   for (j=0; j<n; j++) {
2490637a0070SStefano Zampini     for (i=0; i<m; i++) {
2491637a0070SStefano Zampini       ierr = PetscRandomGetValue(rctx,a+j*lda+i);CHKERRQ(ierr);
2492637a0070SStefano Zampini     }
249373a71a0fSBarry Smith   }
24948c778c55SBarry Smith   ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr);
249573a71a0fSBarry Smith   PetscFunctionReturn(0);
249673a71a0fSBarry Smith }
249773a71a0fSBarry Smith 
24983b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
24993b49f96aSBarry Smith {
25003b49f96aSBarry Smith   PetscFunctionBegin;
25013b49f96aSBarry Smith   *missing = PETSC_FALSE;
25023b49f96aSBarry Smith   PetscFunctionReturn(0);
25033b49f96aSBarry Smith }
250473a71a0fSBarry Smith 
2505ca15aa20SStefano Zampini /* vals is not const */
2506af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
250786aefd0dSHong Zhang {
2508ca15aa20SStefano Zampini   PetscErrorCode ierr;
250986aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2510ca15aa20SStefano Zampini   PetscScalar    *v;
251186aefd0dSHong Zhang 
251286aefd0dSHong Zhang   PetscFunctionBegin;
251386aefd0dSHong Zhang   if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2514ca15aa20SStefano Zampini   ierr  = MatDenseGetArray(A,&v);CHKERRQ(ierr);
2515ca15aa20SStefano Zampini   *vals = v+col*a->lda;
2516ca15aa20SStefano Zampini   ierr  = MatDenseRestoreArray(A,&v);CHKERRQ(ierr);
251786aefd0dSHong Zhang   PetscFunctionReturn(0);
251886aefd0dSHong Zhang }
251986aefd0dSHong Zhang 
2520af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
252186aefd0dSHong Zhang {
252286aefd0dSHong Zhang   PetscFunctionBegin;
252386aefd0dSHong Zhang   *vals = 0; /* user cannot accidently use the array later */
252486aefd0dSHong Zhang   PetscFunctionReturn(0);
252586aefd0dSHong Zhang }
2526abc3b08eSStefano Zampini 
2527289bc588SBarry Smith /* -------------------------------------------------------------------*/
2528a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2529905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2530905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2531905e6a2fSBarry Smith                                         MatMult_SeqDense,
253297304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
25337c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
25347c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2535db4efbfdSBarry Smith                                         0,
2536db4efbfdSBarry Smith                                         0,
2537db4efbfdSBarry Smith                                         0,
2538db4efbfdSBarry Smith                                 /* 10*/ 0,
2539905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2540905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
254141f059aeSBarry Smith                                         MatSOR_SeqDense,
2542ec8511deSBarry Smith                                         MatTranspose_SeqDense,
254397304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2544905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2545905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2546905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2547905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2548c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2549c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2550905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2551905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2552d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2553db4efbfdSBarry Smith                                         0,
2554db4efbfdSBarry Smith                                         0,
2555db4efbfdSBarry Smith                                         0,
2556db4efbfdSBarry Smith                                         0,
25574994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2558273d9f13SBarry Smith                                         0,
2559905e6a2fSBarry Smith                                         0,
256073a71a0fSBarry Smith                                         0,
256173a71a0fSBarry Smith                                         0,
2562d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2563a5ae1ecdSBarry Smith                                         0,
2564a5ae1ecdSBarry Smith                                         0,
2565a5ae1ecdSBarry Smith                                         0,
2566a5ae1ecdSBarry Smith                                         0,
2567d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
25687dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2569a5ae1ecdSBarry Smith                                         0,
25704b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2571a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2572d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2573a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
25747d68702bSBarry Smith                                         MatShift_Basic,
2575a5ae1ecdSBarry Smith                                         0,
25763f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
257773a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2578a5ae1ecdSBarry Smith                                         0,
2579a5ae1ecdSBarry Smith                                         0,
2580a5ae1ecdSBarry Smith                                         0,
2581a5ae1ecdSBarry Smith                                         0,
2582d519adbfSMatthew Knepley                                 /* 54*/ 0,
2583a5ae1ecdSBarry Smith                                         0,
2584a5ae1ecdSBarry Smith                                         0,
2585a5ae1ecdSBarry Smith                                         0,
2586a5ae1ecdSBarry Smith                                         0,
2587d519adbfSMatthew Knepley                                 /* 59*/ 0,
2588e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2589e03a110bSBarry Smith                                         MatView_SeqDense,
2590357abbc8SBarry Smith                                         0,
259197304618SKris Buschelman                                         0,
2592d519adbfSMatthew Knepley                                 /* 64*/ 0,
259397304618SKris Buschelman                                         0,
259497304618SKris Buschelman                                         0,
259597304618SKris Buschelman                                         0,
259697304618SKris Buschelman                                         0,
2597d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
259897304618SKris Buschelman                                         0,
259997304618SKris Buschelman                                         0,
260097304618SKris Buschelman                                         0,
260197304618SKris Buschelman                                         0,
2602d519adbfSMatthew Knepley                                 /* 74*/ 0,
260397304618SKris Buschelman                                         0,
260497304618SKris Buschelman                                         0,
260597304618SKris Buschelman                                         0,
260697304618SKris Buschelman                                         0,
2607d519adbfSMatthew Knepley                                 /* 79*/ 0,
260897304618SKris Buschelman                                         0,
260997304618SKris Buschelman                                         0,
261097304618SKris Buschelman                                         0,
26115bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2612637a0070SStefano Zampini                                         MatIsSymmetric_SeqDense,
26131cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2614865e5f61SKris Buschelman                                         0,
2615865e5f61SKris Buschelman                                         0,
2616865e5f61SKris Buschelman                                         0,
26174222ddf1SHong Zhang                                 /* 89*/ 0,
26184222ddf1SHong Zhang                                         0,
2619a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
26204222ddf1SHong Zhang                                         0,
26214222ddf1SHong Zhang                                         0,
26224222ddf1SHong Zhang                                 /* 94*/ 0,
26234222ddf1SHong Zhang                                         0,
26244222ddf1SHong Zhang                                         0,
262569f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2626284134d9SBarry Smith                                         0,
26274222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
2628284134d9SBarry Smith                                         0,
2629284134d9SBarry Smith                                         0,
2630ba337c44SJed Brown                                         MatConjugate_SeqDense,
2631f73d5cc4SBarry Smith                                         0,
2632ba337c44SJed Brown                                 /*104*/ 0,
2633ba337c44SJed Brown                                         MatRealPart_SeqDense,
2634ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2635985db425SBarry Smith                                         0,
2636985db425SBarry Smith                                         0,
26378208b9aeSStefano Zampini                                 /*109*/ 0,
2638985db425SBarry Smith                                         0,
26398d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2640aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
26413b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2642aabbc4fbSShri Abhyankar                                 /*114*/ 0,
2643aabbc4fbSShri Abhyankar                                         0,
2644aabbc4fbSShri Abhyankar                                         0,
2645aabbc4fbSShri Abhyankar                                         0,
2646aabbc4fbSShri Abhyankar                                         0,
2647aabbc4fbSShri Abhyankar                                 /*119*/ 0,
2648aabbc4fbSShri Abhyankar                                         0,
2649aabbc4fbSShri Abhyankar                                         0,
26500716a85fSBarry Smith                                         0,
26510716a85fSBarry Smith                                         0,
26520716a85fSBarry Smith                                 /*124*/ 0,
26535df89d91SHong Zhang                                         MatGetColumnNorms_SeqDense,
26545df89d91SHong Zhang                                         0,
26555df89d91SHong Zhang                                         0,
26565df89d91SHong Zhang                                         0,
26575df89d91SHong Zhang                                 /*129*/ 0,
26584222ddf1SHong Zhang                                         0,
26594222ddf1SHong Zhang                                         0,
266075648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
26613964eb88SJed Brown                                         0,
26623964eb88SJed Brown                                 /*134*/ 0,
26633964eb88SJed Brown                                         0,
26643964eb88SJed Brown                                         0,
26653964eb88SJed Brown                                         0,
26663964eb88SJed Brown                                         0,
26673964eb88SJed Brown                                 /*139*/ 0,
2668f9426fe0SMark Adams                                         0,
2669d528f656SJakub Kruzik                                         0,
2670d528f656SJakub Kruzik                                         0,
2671d528f656SJakub Kruzik                                         0,
26724222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
26734222ddf1SHong Zhang                                 /*145*/ 0,
26744222ddf1SHong Zhang                                         0,
26754222ddf1SHong Zhang                                         0
2676985db425SBarry Smith };
267790ace30eSBarry Smith 
26784b828684SBarry Smith /*@C
2679fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2680d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2681d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2682289bc588SBarry Smith 
2683d083f849SBarry Smith    Collective
2684db81eaa0SLois Curfman McInnes 
268520563c6bSBarry Smith    Input Parameters:
2686db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
26870c775827SLois Curfman McInnes .  m - number of rows
268818f449edSLois Curfman McInnes .  n - number of columns
26890298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2690dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
269120563c6bSBarry Smith 
269220563c6bSBarry Smith    Output Parameter:
269344cd7ae7SLois Curfman McInnes .  A - the matrix
269420563c6bSBarry Smith 
2695b259b22eSLois Curfman McInnes    Notes:
269618f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
269718f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
26980298fd71SBarry Smith    set data=NULL.
269918f449edSLois Curfman McInnes 
2700027ccd11SLois Curfman McInnes    Level: intermediate
2701027ccd11SLois Curfman McInnes 
270269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
270320563c6bSBarry Smith @*/
27047087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2705289bc588SBarry Smith {
2706dfbe8321SBarry Smith   PetscErrorCode ierr;
27073b2fbd54SBarry Smith 
27083a40ed3dSBarry Smith   PetscFunctionBegin;
2709f69a0ea3SMatthew Knepley   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2710f69a0ea3SMatthew Knepley   ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr);
2711273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
2712273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
2713273d9f13SBarry Smith   PetscFunctionReturn(0);
2714273d9f13SBarry Smith }
2715273d9f13SBarry Smith 
2716273d9f13SBarry Smith /*@C
2717273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2718273d9f13SBarry Smith 
2719d083f849SBarry Smith    Collective
2720273d9f13SBarry Smith 
2721273d9f13SBarry Smith    Input Parameters:
27221c4f3114SJed Brown +  B - the matrix
27230298fd71SBarry Smith -  data - the array (or NULL)
2724273d9f13SBarry Smith 
2725273d9f13SBarry Smith    Notes:
2726273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2727273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2728284134d9SBarry Smith    need not call this routine.
2729273d9f13SBarry Smith 
2730273d9f13SBarry Smith    Level: intermediate
2731273d9f13SBarry Smith 
2732ad16ce7aSStefano Zampini .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatDenseSetLDA()
2733867c911aSBarry Smith 
2734273d9f13SBarry Smith @*/
27357087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
2736273d9f13SBarry Smith {
27374ac538c5SBarry Smith   PetscErrorCode ierr;
2738a23d5eceSKris Buschelman 
2739a23d5eceSKris Buschelman   PetscFunctionBegin;
2740d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
27414ac538c5SBarry Smith   ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr);
2742a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2743a23d5eceSKris Buschelman }
2744a23d5eceSKris Buschelman 
27457087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
2746a23d5eceSKris Buschelman {
2747ad16ce7aSStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
2748dfbe8321SBarry Smith   PetscErrorCode ierr;
2749273d9f13SBarry Smith 
2750273d9f13SBarry Smith   PetscFunctionBegin;
2751273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2752a868139aSShri Abhyankar 
275334ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr);
275434ef9618SShri Abhyankar   ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr);
275534ef9618SShri Abhyankar 
2756ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
275786d161a7SShri Abhyankar 
2758ad16ce7aSStefano Zampini   ierr = PetscIntMultError(b->lda,B->cmap->n,NULL);CHKERRQ(ierr);
27599e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
27609e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2761ad16ce7aSStefano Zampini     ierr = PetscCalloc1((size_t)b->lda*B->cmap->n,&b->v);CHKERRQ(ierr);
2762ad16ce7aSStefano Zampini     ierr = PetscLogObjectMemory((PetscObject)B,b->lda*B->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr);
27632205254eSKarl Rupp 
27649e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2765273d9f13SBarry Smith   } else { /* user-allocated storage */
27669e8f95c4SLisandro Dalcin     if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); }
2767273d9f13SBarry Smith     b->v          = data;
2768273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2769273d9f13SBarry Smith   }
27700450473dSBarry Smith   B->assembled = PETSC_TRUE;
2771273d9f13SBarry Smith   PetscFunctionReturn(0);
2772273d9f13SBarry Smith }
2773273d9f13SBarry Smith 
277465b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
2775cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
27768baccfbdSHong Zhang {
2777d77f618aSHong Zhang   Mat               mat_elemental;
2778d77f618aSHong Zhang   PetscErrorCode    ierr;
27791683a169SBarry Smith   const PetscScalar *array;
27801683a169SBarry Smith   PetscScalar       *v_colwise;
2781d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
2782d77f618aSHong Zhang 
27838baccfbdSHong Zhang   PetscFunctionBegin;
2784d77f618aSHong Zhang   ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr);
27851683a169SBarry Smith   ierr = MatDenseGetArrayRead(A,&array);CHKERRQ(ierr);
2786d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2787d77f618aSHong Zhang   k = 0;
2788d77f618aSHong Zhang   for (j=0; j<N; j++) {
2789d77f618aSHong Zhang     cols[j] = j;
2790d77f618aSHong Zhang     for (i=0; i<M; i++) {
2791d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
2792d77f618aSHong Zhang     }
2793d77f618aSHong Zhang   }
2794d77f618aSHong Zhang   for (i=0; i<M; i++) {
2795d77f618aSHong Zhang     rows[i] = i;
2796d77f618aSHong Zhang   }
27971683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(A,&array);CHKERRQ(ierr);
2798d77f618aSHong Zhang 
2799d77f618aSHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr);
2800d77f618aSHong Zhang   ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr);
2801d77f618aSHong Zhang   ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr);
2802d77f618aSHong Zhang   ierr = MatSetUp(mat_elemental);CHKERRQ(ierr);
2803d77f618aSHong Zhang 
2804d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
2805d77f618aSHong Zhang   ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr);
2806d77f618aSHong Zhang   ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2807d77f618aSHong Zhang   ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2808d77f618aSHong Zhang   ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr);
2809d77f618aSHong Zhang 
2810511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
281128be2f97SBarry Smith     ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr);
2812d77f618aSHong Zhang   } else {
2813d77f618aSHong Zhang     *newmat = mat_elemental;
2814d77f618aSHong Zhang   }
28158baccfbdSHong Zhang   PetscFunctionReturn(0);
28168baccfbdSHong Zhang }
281765b80a83SHong Zhang #endif
28188baccfbdSHong Zhang 
2819ad16ce7aSStefano Zampini static PetscErrorCode  MatDenseSetLDA_SeqDense(Mat B,PetscInt lda)
28201b807ce4Svictorle {
28211b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
282221a2c019SBarry Smith 
28231b807ce4Svictorle   PetscFunctionBegin;
2824e32f2f54SBarry 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);
28251b807ce4Svictorle   b->lda = lda;
28261b807ce4Svictorle   PetscFunctionReturn(0);
28271b807ce4Svictorle }
28281b807ce4Svictorle 
2829d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
2830d528f656SJakub Kruzik {
2831d528f656SJakub Kruzik   PetscErrorCode ierr;
2832d528f656SJakub Kruzik   PetscMPIInt    size;
2833d528f656SJakub Kruzik 
2834d528f656SJakub Kruzik   PetscFunctionBegin;
2835d528f656SJakub Kruzik   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
2836d528f656SJakub Kruzik   if (size == 1) {
2837d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
2838d528f656SJakub Kruzik       ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr);
2839d528f656SJakub Kruzik     } else {
2840d528f656SJakub Kruzik       ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2841d528f656SJakub Kruzik     }
2842d528f656SJakub Kruzik   } else {
2843d528f656SJakub Kruzik     ierr = MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat);CHKERRQ(ierr);
2844d528f656SJakub Kruzik   }
2845d528f656SJakub Kruzik   PetscFunctionReturn(0);
2846d528f656SJakub Kruzik }
2847d528f656SJakub Kruzik 
28486947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
28496947451fSStefano Zampini {
28506947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
28516947451fSStefano Zampini   PetscErrorCode ierr;
28526947451fSStefano Zampini 
28536947451fSStefano Zampini   PetscFunctionBegin;
2854*5ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
2855*5ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
28566947451fSStefano Zampini   if (!a->cvec) {
28576947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
28586947451fSStefano Zampini   }
28596947451fSStefano Zampini   a->vecinuse = col + 1;
28606947451fSStefano Zampini   ierr = MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
28616947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
28626947451fSStefano Zampini   *v   = a->cvec;
28636947451fSStefano Zampini   PetscFunctionReturn(0);
28646947451fSStefano Zampini }
28656947451fSStefano Zampini 
28666947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
28676947451fSStefano Zampini {
28686947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
28696947451fSStefano Zampini   PetscErrorCode ierr;
28706947451fSStefano Zampini 
28716947451fSStefano Zampini   PetscFunctionBegin;
2872*5ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
28736947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
28746947451fSStefano Zampini   a->vecinuse = 0;
28756947451fSStefano Zampini   ierr = MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
28766947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
28776947451fSStefano Zampini   *v   = NULL;
28786947451fSStefano Zampini   PetscFunctionReturn(0);
28796947451fSStefano Zampini }
28806947451fSStefano Zampini 
28816947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
28826947451fSStefano Zampini {
28836947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
28846947451fSStefano Zampini   PetscErrorCode ierr;
28856947451fSStefano Zampini 
28866947451fSStefano Zampini   PetscFunctionBegin;
2887*5ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
2888*5ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
28896947451fSStefano Zampini   if (!a->cvec) {
28906947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
28916947451fSStefano Zampini   }
28926947451fSStefano Zampini   a->vecinuse = col + 1;
28936947451fSStefano Zampini   ierr = MatDenseGetArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
28946947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
28956947451fSStefano Zampini   ierr = VecLockReadPush(a->cvec);CHKERRQ(ierr);
28966947451fSStefano Zampini   *v   = a->cvec;
28976947451fSStefano Zampini   PetscFunctionReturn(0);
28986947451fSStefano Zampini }
28996947451fSStefano Zampini 
29006947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
29016947451fSStefano Zampini {
29026947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
29036947451fSStefano Zampini   PetscErrorCode ierr;
29046947451fSStefano Zampini 
29056947451fSStefano Zampini   PetscFunctionBegin;
2906*5ea7661aSPierre Jolivet   if (!a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
29076947451fSStefano Zampini   if (!a->cvec) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
29086947451fSStefano Zampini   a->vecinuse = 0;
29096947451fSStefano Zampini   ierr = MatDenseRestoreArrayRead(A,&a->ptrinuse);CHKERRQ(ierr);
29106947451fSStefano Zampini   ierr = VecLockReadPop(a->cvec);CHKERRQ(ierr);
29116947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
29126947451fSStefano Zampini   *v   = NULL;
29136947451fSStefano Zampini   PetscFunctionReturn(0);
29146947451fSStefano Zampini }
29156947451fSStefano Zampini 
29166947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
29176947451fSStefano Zampini {
29186947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
29196947451fSStefano Zampini   PetscErrorCode ierr;
29206947451fSStefano Zampini 
29216947451fSStefano Zampini   PetscFunctionBegin;
2922*5ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
2923*5ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
29246947451fSStefano Zampini   if (!a->cvec) {
29256947451fSStefano Zampini     ierr = VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec);CHKERRQ(ierr);
29266947451fSStefano Zampini   }
29276947451fSStefano Zampini   a->vecinuse = col + 1;
29286947451fSStefano Zampini   ierr = MatDenseGetArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
29296947451fSStefano Zampini   ierr = VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda);CHKERRQ(ierr);
29306947451fSStefano Zampini   *v   = a->cvec;
29316947451fSStefano Zampini   PetscFunctionReturn(0);
29326947451fSStefano Zampini }
29336947451fSStefano Zampini 
29346947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite_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;
2940*5ea7661aSPierre 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 = MatDenseRestoreArrayWrite(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
29446947451fSStefano Zampini   ierr = VecResetArray(a->cvec);CHKERRQ(ierr);
29456947451fSStefano Zampini   *v   = NULL;
29466947451fSStefano Zampini   PetscFunctionReturn(0);
29476947451fSStefano Zampini }
29486947451fSStefano Zampini 
2949*5ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
2950*5ea7661aSPierre Jolivet {
2951*5ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2952*5ea7661aSPierre Jolivet   PetscErrorCode ierr;
2953*5ea7661aSPierre Jolivet 
2954*5ea7661aSPierre Jolivet   PetscFunctionBegin;
2955*5ea7661aSPierre Jolivet   if (a->vecinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
2956*5ea7661aSPierre Jolivet   if (a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
2957*5ea7661aSPierre Jolivet   if (a->cmat && cend-cbegin != a->cmat->cmap->N) {
2958*5ea7661aSPierre Jolivet     ierr = MatDestroy(&a->cmat);CHKERRQ(ierr);
2959*5ea7661aSPierre Jolivet   }
2960*5ea7661aSPierre Jolivet   ierr = MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
2961*5ea7661aSPierre Jolivet   if (!a->cmat) {
2962*5ea7661aSPierre Jolivet     ierr = MatCreateDense(PetscObjectComm((PetscObject)A),A->rmap->n,PETSC_DECIDE,A->rmap->N,cend-cbegin,(PetscScalar*)a->ptrinuse + (size_t)cbegin * (size_t)a->lda,&a->cmat);CHKERRQ(ierr);
2963*5ea7661aSPierre Jolivet     ierr = MatDenseSetLDA(a->cmat,a->lda);CHKERRQ(ierr);
2964*5ea7661aSPierre Jolivet   } else {
2965*5ea7661aSPierre Jolivet     ierr = MatDensePlaceArray(a->cmat,a->ptrinuse + (size_t)cbegin * (size_t)a->lda);CHKERRQ(ierr);
2966*5ea7661aSPierre Jolivet   }
2967*5ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
2968*5ea7661aSPierre Jolivet   *v = a->cmat;
2969*5ea7661aSPierre Jolivet   PetscFunctionReturn(0);
2970*5ea7661aSPierre Jolivet }
2971*5ea7661aSPierre Jolivet 
2972*5ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A,Mat *v)
2973*5ea7661aSPierre Jolivet {
2974*5ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2975*5ea7661aSPierre Jolivet   PetscErrorCode ierr;
2976*5ea7661aSPierre Jolivet 
2977*5ea7661aSPierre Jolivet   PetscFunctionBegin;
2978*5ea7661aSPierre Jolivet   if (!a->matinuse) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetSubMatrix() first");
2979*5ea7661aSPierre Jolivet   if (!a->cmat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column matrix");
2980*5ea7661aSPierre Jolivet   a->matinuse = 0;
2981*5ea7661aSPierre Jolivet   ierr = MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse);CHKERRQ(ierr);
2982*5ea7661aSPierre Jolivet   ierr = MatDenseResetArray(a->cmat);CHKERRQ(ierr);
2983*5ea7661aSPierre Jolivet   *v   = NULL;
2984*5ea7661aSPierre Jolivet   PetscFunctionReturn(0);
2985*5ea7661aSPierre Jolivet }
2986*5ea7661aSPierre Jolivet 
29870bad9183SKris Buschelman /*MC
2988fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
29890bad9183SKris Buschelman 
29900bad9183SKris Buschelman    Options Database Keys:
29910bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
29920bad9183SKris Buschelman 
29930bad9183SKris Buschelman   Level: beginner
29940bad9183SKris Buschelman 
299589665df3SBarry Smith .seealso: MatCreateSeqDense()
299689665df3SBarry Smith 
29970bad9183SKris Buschelman M*/
2998ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
2999273d9f13SBarry Smith {
3000273d9f13SBarry Smith   Mat_SeqDense   *b;
3001dfbe8321SBarry Smith   PetscErrorCode ierr;
30027c334f02SBarry Smith   PetscMPIInt    size;
3003273d9f13SBarry Smith 
3004273d9f13SBarry Smith   PetscFunctionBegin;
3005ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr);
3006e32f2f54SBarry Smith   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
300755659b69SBarry Smith 
3008b00a9115SJed Brown   ierr    = PetscNewLog(B,&b);CHKERRQ(ierr);
3009549d3d68SSatish Balay   ierr    = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
301044cd7ae7SLois Curfman McInnes   B->data = (void*)b;
301118f449edSLois Curfman McInnes 
3012273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
30134e220ebcSLois Curfman McInnes 
301449a6ff4bSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense);CHKERRQ(ierr);
3015ad16ce7aSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseSetLDA_C",MatDenseSetLDA_SeqDense);CHKERRQ(ierr);
3016bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
30178572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
3018d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense);CHKERRQ(ierr);
3019d3042a70SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense);CHKERRQ(ierr);
3020d5ea218eSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseReplaceArray_C",MatDenseReplaceArray_SeqDense);CHKERRQ(ierr);
30218572280aSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
3022715b7558SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
30236947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayWrite_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr);
30246947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayWrite_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr);
3025bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr);
30268baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
30278baccfbdSHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr);
30288baccfbdSHong Zhang #endif
30292bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
30302bf066beSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA);CHKERRQ(ierr);
30314222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
30324222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
3033637a0070SStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
30342bf066beSStefano Zampini #endif
3035bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr);
30364222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense);CHKERRQ(ierr);
30374222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense);CHKERRQ(ierr);
30384222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
30394222ddf1SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense);CHKERRQ(ierr);
304096e6d5c4SRichard Tran Mills 
3041af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense);CHKERRQ(ierr);
3042af53bab2SHong Zhang   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense);CHKERRQ(ierr);
30436947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVec_C",MatDenseGetColumnVec_SeqDense);CHKERRQ(ierr);
30446947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVec_C",MatDenseRestoreColumnVec_SeqDense);CHKERRQ(ierr);
30456947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecRead_C",MatDenseGetColumnVecRead_SeqDense);CHKERRQ(ierr);
30466947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecRead_C",MatDenseRestoreColumnVecRead_SeqDense);CHKERRQ(ierr);
30476947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecWrite_C",MatDenseGetColumnVecWrite_SeqDense);CHKERRQ(ierr);
30486947451fSStefano Zampini   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecWrite_C",MatDenseRestoreColumnVecWrite_SeqDense);CHKERRQ(ierr);
3049*5ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetSubMatrix_C",MatDenseGetSubMatrix_SeqDense);CHKERRQ(ierr);
3050*5ea7661aSPierre Jolivet   ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreSubMatrix_C",MatDenseRestoreSubMatrix_SeqDense);CHKERRQ(ierr);
305117667f90SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr);
30523a40ed3dSBarry Smith   PetscFunctionReturn(0);
3053289bc588SBarry Smith }
305486aefd0dSHong Zhang 
305586aefd0dSHong Zhang /*@C
3056af53bab2SHong 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.
305786aefd0dSHong Zhang 
305886aefd0dSHong Zhang    Not Collective
305986aefd0dSHong Zhang 
3060*5ea7661aSPierre Jolivet    Input Parameters:
306186aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
306286aefd0dSHong Zhang -  col - column index
306386aefd0dSHong Zhang 
306486aefd0dSHong Zhang    Output Parameter:
306586aefd0dSHong Zhang .  vals - pointer to the data
306686aefd0dSHong Zhang 
306786aefd0dSHong Zhang    Level: intermediate
306886aefd0dSHong Zhang 
306986aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
307086aefd0dSHong Zhang @*/
307186aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
307286aefd0dSHong Zhang {
307386aefd0dSHong Zhang   PetscErrorCode ierr;
307486aefd0dSHong Zhang 
307586aefd0dSHong Zhang   PetscFunctionBegin;
3076d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3077d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3078d5ea218eSStefano Zampini   PetscValidPointer(vals,3);
307986aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));CHKERRQ(ierr);
308086aefd0dSHong Zhang   PetscFunctionReturn(0);
308186aefd0dSHong Zhang }
308286aefd0dSHong Zhang 
308386aefd0dSHong Zhang /*@C
308486aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
308586aefd0dSHong Zhang 
308686aefd0dSHong Zhang    Not Collective
308786aefd0dSHong Zhang 
308886aefd0dSHong Zhang    Input Parameter:
308986aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
309086aefd0dSHong Zhang 
309186aefd0dSHong Zhang    Output Parameter:
309286aefd0dSHong Zhang .  vals - pointer to the data
309386aefd0dSHong Zhang 
309486aefd0dSHong Zhang    Level: intermediate
309586aefd0dSHong Zhang 
309686aefd0dSHong Zhang .seealso: MatDenseGetColumn()
309786aefd0dSHong Zhang @*/
309886aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
309986aefd0dSHong Zhang {
310086aefd0dSHong Zhang   PetscErrorCode ierr;
310186aefd0dSHong Zhang 
310286aefd0dSHong Zhang   PetscFunctionBegin;
3103d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3104d5ea218eSStefano Zampini   PetscValidPointer(vals,2);
310586aefd0dSHong Zhang   ierr = PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));CHKERRQ(ierr);
310686aefd0dSHong Zhang   PetscFunctionReturn(0);
310786aefd0dSHong Zhang }
31086947451fSStefano Zampini 
31096947451fSStefano Zampini /*@C
31106947451fSStefano Zampini    MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec.
31116947451fSStefano Zampini 
31126947451fSStefano Zampini    Collective
31136947451fSStefano Zampini 
3114*5ea7661aSPierre Jolivet    Input Parameters:
31156947451fSStefano Zampini +  mat - the Mat object
31166947451fSStefano Zampini -  col - the column index
31176947451fSStefano Zampini 
31186947451fSStefano Zampini    Output Parameter:
31196947451fSStefano Zampini .  v - the vector
31206947451fSStefano Zampini 
31216947451fSStefano Zampini    Notes:
31226947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed.
31236947451fSStefano Zampini      Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access.
31246947451fSStefano Zampini 
31256947451fSStefano Zampini    Level: intermediate
31266947451fSStefano Zampini 
31276947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
31286947451fSStefano Zampini @*/
31296947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec(Mat A,PetscInt col,Vec *v)
31306947451fSStefano Zampini {
31316947451fSStefano Zampini   PetscErrorCode ierr;
31326947451fSStefano Zampini 
31336947451fSStefano Zampini   PetscFunctionBegin;
31346947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
31356947451fSStefano Zampini   PetscValidType(A,1);
31366947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
31376947451fSStefano Zampini   PetscValidPointer(v,3);
31386947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
31396947451fSStefano 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);
31406947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
31416947451fSStefano Zampini   PetscFunctionReturn(0);
31426947451fSStefano Zampini }
31436947451fSStefano Zampini 
31446947451fSStefano Zampini /*@C
31456947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
31466947451fSStefano Zampini 
31476947451fSStefano Zampini    Collective
31486947451fSStefano Zampini 
3149*5ea7661aSPierre Jolivet    Input Parameters:
31506947451fSStefano Zampini +  mat - the Mat object
31516947451fSStefano Zampini .  col - the column index
31526947451fSStefano Zampini -  v - the Vec object
31536947451fSStefano Zampini 
31546947451fSStefano Zampini    Level: intermediate
31556947451fSStefano Zampini 
31566947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
31576947451fSStefano Zampini @*/
31586947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec *v)
31596947451fSStefano Zampini {
31606947451fSStefano Zampini   PetscErrorCode ierr;
31616947451fSStefano Zampini 
31626947451fSStefano Zampini   PetscFunctionBegin;
31636947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
31646947451fSStefano Zampini   PetscValidType(A,1);
31656947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
31666947451fSStefano Zampini   PetscValidPointer(v,3);
31676947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
31686947451fSStefano 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);
31696947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
31706947451fSStefano Zampini   PetscFunctionReturn(0);
31716947451fSStefano Zampini }
31726947451fSStefano Zampini 
31736947451fSStefano Zampini /*@C
31746947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
31756947451fSStefano Zampini 
31766947451fSStefano Zampini    Collective
31776947451fSStefano Zampini 
3178*5ea7661aSPierre Jolivet    Input Parameters:
31796947451fSStefano Zampini +  mat - the Mat object
31806947451fSStefano Zampini -  col - the column index
31816947451fSStefano Zampini 
31826947451fSStefano Zampini    Output Parameter:
31836947451fSStefano Zampini .  v - the vector
31846947451fSStefano Zampini 
31856947451fSStefano Zampini    Notes:
31866947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
31876947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
31886947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
31896947451fSStefano Zampini 
31906947451fSStefano Zampini    Level: intermediate
31916947451fSStefano Zampini 
31926947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
31936947451fSStefano Zampini @*/
31946947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec *v)
31956947451fSStefano Zampini {
31966947451fSStefano Zampini   PetscErrorCode ierr;
31976947451fSStefano Zampini 
31986947451fSStefano Zampini   PetscFunctionBegin;
31996947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
32006947451fSStefano Zampini   PetscValidType(A,1);
32016947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
32026947451fSStefano Zampini   PetscValidPointer(v,3);
32036947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
32046947451fSStefano 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);
32056947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
32066947451fSStefano Zampini   PetscFunctionReturn(0);
32076947451fSStefano Zampini }
32086947451fSStefano Zampini 
32096947451fSStefano Zampini /*@C
32106947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
32116947451fSStefano Zampini 
32126947451fSStefano Zampini    Collective
32136947451fSStefano Zampini 
3214*5ea7661aSPierre Jolivet    Input Parameters:
32156947451fSStefano Zampini +  mat - the Mat object
32166947451fSStefano Zampini .  col - the column index
32176947451fSStefano Zampini -  v - the Vec object
32186947451fSStefano Zampini 
32196947451fSStefano Zampini    Level: intermediate
32206947451fSStefano Zampini 
32216947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecWrite()
32226947451fSStefano Zampini @*/
32236947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec *v)
32246947451fSStefano Zampini {
32256947451fSStefano Zampini   PetscErrorCode ierr;
32266947451fSStefano Zampini 
32276947451fSStefano Zampini   PetscFunctionBegin;
32286947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
32296947451fSStefano Zampini   PetscValidType(A,1);
32306947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
32316947451fSStefano Zampini   PetscValidPointer(v,3);
32326947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
32336947451fSStefano 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);
32346947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
32356947451fSStefano Zampini   PetscFunctionReturn(0);
32366947451fSStefano Zampini }
32376947451fSStefano Zampini 
32386947451fSStefano Zampini /*@C
32396947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
32406947451fSStefano Zampini 
32416947451fSStefano Zampini    Collective
32426947451fSStefano Zampini 
3243*5ea7661aSPierre Jolivet    Input Parameters:
32446947451fSStefano Zampini +  mat - the Mat object
32456947451fSStefano Zampini -  col - the column index
32466947451fSStefano Zampini 
32476947451fSStefano Zampini    Output Parameter:
32486947451fSStefano Zampini .  v - the vector
32496947451fSStefano Zampini 
32506947451fSStefano Zampini    Notes:
32516947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
32526947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
32536947451fSStefano Zampini 
32546947451fSStefano Zampini    Level: intermediate
32556947451fSStefano Zampini 
32566947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
32576947451fSStefano Zampini @*/
32586947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec *v)
32596947451fSStefano Zampini {
32606947451fSStefano Zampini   PetscErrorCode ierr;
32616947451fSStefano Zampini 
32626947451fSStefano Zampini   PetscFunctionBegin;
32636947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
32646947451fSStefano Zampini   PetscValidType(A,1);
32656947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
32666947451fSStefano Zampini   PetscValidPointer(v,3);
32676947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
32686947451fSStefano 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);
32696947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseGetColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
32706947451fSStefano Zampini   PetscFunctionReturn(0);
32716947451fSStefano Zampini }
32726947451fSStefano Zampini 
32736947451fSStefano Zampini /*@C
32746947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
32756947451fSStefano Zampini 
32766947451fSStefano Zampini    Collective
32776947451fSStefano Zampini 
3278*5ea7661aSPierre Jolivet    Input Parameters:
32796947451fSStefano Zampini +  mat - the Mat object
32806947451fSStefano Zampini .  col - the column index
32816947451fSStefano Zampini -  v - the Vec object
32826947451fSStefano Zampini 
32836947451fSStefano Zampini    Level: intermediate
32846947451fSStefano Zampini 
32856947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead()
32866947451fSStefano Zampini @*/
32876947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec *v)
32886947451fSStefano Zampini {
32896947451fSStefano Zampini   PetscErrorCode ierr;
32906947451fSStefano Zampini 
32916947451fSStefano Zampini   PetscFunctionBegin;
32926947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
32936947451fSStefano Zampini   PetscValidType(A,1);
32946947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
32956947451fSStefano Zampini   PetscValidPointer(v,3);
32966947451fSStefano Zampini   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
32976947451fSStefano 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);
32986947451fSStefano Zampini   ierr = PetscUseMethod(A,"MatDenseRestoreColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));CHKERRQ(ierr);
32996947451fSStefano Zampini   PetscFunctionReturn(0);
33006947451fSStefano Zampini }
3301*5ea7661aSPierre Jolivet 
3302*5ea7661aSPierre Jolivet /*@C
3303*5ea7661aSPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of columns of a dense matrix, represented as a Mat.
3304*5ea7661aSPierre Jolivet 
3305*5ea7661aSPierre Jolivet    Collective
3306*5ea7661aSPierre Jolivet 
3307*5ea7661aSPierre Jolivet    Input Parameters:
3308*5ea7661aSPierre Jolivet +  mat - the Mat object
3309*5ea7661aSPierre Jolivet .  cbegin - the first index in the block
3310*5ea7661aSPierre Jolivet -  cend - the last index in the block
3311*5ea7661aSPierre Jolivet 
3312*5ea7661aSPierre Jolivet    Output Parameter:
3313*5ea7661aSPierre Jolivet .  v - the matrix
3314*5ea7661aSPierre Jolivet 
3315*5ea7661aSPierre Jolivet    Notes:
3316*5ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
3317*5ea7661aSPierre Jolivet 
3318*5ea7661aSPierre Jolivet    Level: intermediate
3319*5ea7661aSPierre Jolivet 
3320*5ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseRestoreSubMatrix()
3321*5ea7661aSPierre Jolivet @*/
3322*5ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
3323*5ea7661aSPierre Jolivet {
3324*5ea7661aSPierre Jolivet   PetscErrorCode ierr;
3325*5ea7661aSPierre Jolivet 
3326*5ea7661aSPierre Jolivet   PetscFunctionBegin;
3327*5ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3328*5ea7661aSPierre Jolivet   PetscValidType(A,1);
3329*5ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cbegin,2);
3330*5ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cend,3);
3331*5ea7661aSPierre Jolivet   PetscValidPointer(v,4);
3332*5ea7661aSPierre Jolivet   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3333*5ea7661aSPierre 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);
3334*5ea7661aSPierre Jolivet   if (cend < 0 || cend > A->cmap->N || cend <= cbegin) SETERRQ3(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid cend %D, should be in [0,%D) and strictly greater than cbegin %D",cend,A->cmap->N,cbegin);
3335*5ea7661aSPierre Jolivet   ierr = PetscUseMethod(A,"MatDenseGetSubMatrix_C",(Mat,PetscInt,PetscInt,Mat*),(A,cbegin,cend,v));CHKERRQ(ierr);
3336*5ea7661aSPierre Jolivet   PetscFunctionReturn(0);
3337*5ea7661aSPierre Jolivet }
3338*5ea7661aSPierre Jolivet 
3339*5ea7661aSPierre Jolivet /*@C
3340*5ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
3341*5ea7661aSPierre Jolivet 
3342*5ea7661aSPierre Jolivet    Collective
3343*5ea7661aSPierre Jolivet 
3344*5ea7661aSPierre Jolivet    Input Parameters:
3345*5ea7661aSPierre Jolivet +  mat - the Mat object
3346*5ea7661aSPierre Jolivet -  v - the Mat object
3347*5ea7661aSPierre Jolivet 
3348*5ea7661aSPierre Jolivet    Level: intermediate
3349*5ea7661aSPierre Jolivet 
3350*5ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseGetSubMatrix()
3351*5ea7661aSPierre Jolivet @*/
3352*5ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix(Mat A,Mat *v)
3353*5ea7661aSPierre Jolivet {
3354*5ea7661aSPierre Jolivet   PetscErrorCode ierr;
3355*5ea7661aSPierre Jolivet 
3356*5ea7661aSPierre Jolivet   PetscFunctionBegin;
3357*5ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3358*5ea7661aSPierre Jolivet   PetscValidType(A,1);
3359*5ea7661aSPierre Jolivet   PetscValidPointer(v,2);
3360*5ea7661aSPierre Jolivet   if (!A->preallocated) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3361*5ea7661aSPierre Jolivet   ierr = PetscUseMethod(A,"MatDenseRestoreSubMatrix_C",(Mat,Mat*),(A,v));CHKERRQ(ierr);
3362*5ea7661aSPierre Jolivet   PetscFunctionReturn(0);
3363*5ea7661aSPierre Jolivet }
3364