xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 2e956fe4fc852fabc23b437482e1fb7b77fddb0d)
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;
168c178816SStefano Zampini 
178c178816SStefano Zampini   PetscFunctionBegin;
1808401ef6SPierre Jolivet   PetscCheck(A->rmap->n == A->cmap->n,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot symmetrize a rectangular matrix");
199566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
208c178816SStefano Zampini   if (!hermitian) {
218c178816SStefano Zampini     for (k=0;k<n;k++) {
228c178816SStefano Zampini       for (j=k;j<n;j++) {
23ca15aa20SStefano Zampini         v[j*mat->lda + k] = v[k*mat->lda + j];
248c178816SStefano Zampini       }
258c178816SStefano Zampini     }
268c178816SStefano Zampini   } else {
278c178816SStefano Zampini     for (k=0;k<n;k++) {
288c178816SStefano Zampini       for (j=k;j<n;j++) {
29ca15aa20SStefano Zampini         v[j*mat->lda + k] = PetscConj(v[k*mat->lda + j]);
308c178816SStefano Zampini       }
318c178816SStefano Zampini     }
328c178816SStefano Zampini   }
339566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
348c178816SStefano Zampini   PetscFunctionReturn(0);
358c178816SStefano Zampini }
368c178816SStefano Zampini 
3705709791SSatish Balay PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A)
388c178816SStefano Zampini {
398c178816SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
408c178816SStefano Zampini   PetscBLASInt   info,n;
418c178816SStefano Zampini 
428c178816SStefano Zampini   PetscFunctionBegin;
438c178816SStefano Zampini   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
449566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
458c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
4628b400f6SJacob Faibussowitsch     PetscCheck(mat->pivots,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
478c178816SStefano Zampini     if (!mat->fwork) {
488c178816SStefano Zampini       mat->lfwork = n;
499566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
509566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
518c178816SStefano Zampini     }
529566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
538c178816SStefano Zampini     PetscStackCallBLAS("LAPACKgetri",LAPACKgetri_(&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
549566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
559566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0));
568c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
578c178816SStefano Zampini     if (A->spd) {
589566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
598c178816SStefano Zampini       PetscStackCallBLAS("LAPACKpotri",LAPACKpotri_("L",&n,mat->v,&mat->lda,&info));
609566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
619566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A,PETSC_TRUE));
628c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
638c178816SStefano Zampini     } else if (A->hermitian) {
6428b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
6528b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
669566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
678c178816SStefano Zampini       PetscStackCallBLAS("LAPACKhetri",LAPACKhetri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
689566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
699566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A,PETSC_TRUE));
708c178816SStefano Zampini #endif
718c178816SStefano Zampini     } else { /* symmetric case */
7228b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
7328b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
749566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
758c178816SStefano Zampini       PetscStackCallBLAS("LAPACKsytri",LAPACKsytri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
769566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
779566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A,PETSC_FALSE));
788c178816SStefano Zampini     }
7928b400f6SJacob Faibussowitsch     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad Inversion: zero pivot in row %" PetscInt_FMT,(PetscInt)info-1);
809566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0));
818c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
828c178816SStefano Zampini 
838c178816SStefano Zampini   A->ops->solve             = NULL;
848c178816SStefano Zampini   A->ops->matsolve          = NULL;
858c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
868c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
878c178816SStefano Zampini   A->ops->solveadd          = NULL;
888c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
898c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
909566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
918c178816SStefano Zampini   PetscFunctionReturn(0);
928c178816SStefano Zampini }
938c178816SStefano Zampini 
943f49a652SStefano Zampini PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
953f49a652SStefano Zampini {
963f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
973f49a652SStefano Zampini   PetscInt          m  = l->lda, n = A->cmap->n,r = A->rmap->n, i,j;
98ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
993f49a652SStefano Zampini   const PetscScalar *xx;
1003f49a652SStefano Zampini 
1013f49a652SStefano Zampini   PetscFunctionBegin;
10276bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1033f49a652SStefano Zampini     for (i=0; i<N; i++) {
10408401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
10508401ef6SPierre Jolivet       PetscCheck(rows[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %" PetscInt_FMT " requested to be zeroed greater than or equal number of rows %" PetscInt_FMT,rows[i],A->rmap->n);
10608401ef6SPierre Jolivet       PetscCheck(rows[i] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Col %" PetscInt_FMT " requested to be zeroed greater than or equal number of cols %" PetscInt_FMT,rows[i],A->cmap->n);
1073f49a652SStefano Zampini     }
10876bd3646SJed Brown   }
109ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1103f49a652SStefano Zampini 
1113f49a652SStefano Zampini   /* fix right hand side if needed */
1123f49a652SStefano Zampini   if (x && b) {
1136c4d906cSStefano Zampini     Vec xt;
1146c4d906cSStefano Zampini 
11508401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1169566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(x,&xt));
1179566063dSJacob Faibussowitsch     PetscCall(VecCopy(x,xt));
1189566063dSJacob Faibussowitsch     PetscCall(VecScale(xt,-1.0));
1199566063dSJacob Faibussowitsch     PetscCall(MatMultAdd(A,xt,b,b));
1209566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&xt));
1219566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x,&xx));
1229566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b,&bb));
1233f49a652SStefano Zampini     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
1249566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x,&xx));
1259566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b,&bb));
1263f49a652SStefano Zampini   }
1273f49a652SStefano Zampini 
1289566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
1293f49a652SStefano Zampini   for (i=0; i<N; i++) {
130ca15aa20SStefano Zampini     slot = v + rows[i]*m;
1319566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(slot,r));
1323f49a652SStefano Zampini   }
1333f49a652SStefano Zampini   for (i=0; i<N; i++) {
134ca15aa20SStefano Zampini     slot = v + rows[i];
1353f49a652SStefano Zampini     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
1363f49a652SStefano Zampini   }
1373f49a652SStefano Zampini   if (diag != 0.0) {
13808401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1393f49a652SStefano Zampini     for (i=0; i<N; i++) {
140ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1413f49a652SStefano Zampini       *slot = diag;
1423f49a652SStefano Zampini     }
1433f49a652SStefano Zampini   }
1449566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
1453f49a652SStefano Zampini   PetscFunctionReturn(0);
1463f49a652SStefano Zampini }
1473f49a652SStefano Zampini 
148abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C)
149abc3b08eSStefano Zampini {
150abc3b08eSStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)(C->data);
151abc3b08eSStefano Zampini 
152abc3b08eSStefano Zampini   PetscFunctionBegin;
153ca15aa20SStefano Zampini   if (c->ptapwork) {
1549566063dSJacob Faibussowitsch     PetscCall((*C->ops->matmultnumeric)(A,P,c->ptapwork));
1559566063dSJacob Faibussowitsch     PetscCall((*C->ops->transposematmultnumeric)(P,c->ptapwork,C));
1564222ddf1SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"Must call MatPtAPSymbolic_SeqDense_SeqDense() first");
157abc3b08eSStefano Zampini   PetscFunctionReturn(0);
158abc3b08eSStefano Zampini }
159abc3b08eSStefano Zampini 
1604222ddf1SHong Zhang PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat C)
161abc3b08eSStefano Zampini {
162abc3b08eSStefano Zampini   Mat_SeqDense   *c;
1637a3c3d58SStefano Zampini   PetscBool      cisdense;
164abc3b08eSStefano Zampini 
165abc3b08eSStefano Zampini   PetscFunctionBegin;
1669566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,P->cmap->n,P->cmap->n,P->cmap->N,P->cmap->N));
1679566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
1687a3c3d58SStefano Zampini   if (!cisdense) {
1697a3c3d58SStefano Zampini     PetscBool flg;
1707a3c3d58SStefano Zampini 
1719566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)P,((PetscObject)A)->type_name,&flg));
1729566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
1737a3c3d58SStefano Zampini   }
1749566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
1754222ddf1SHong Zhang   c    = (Mat_SeqDense*)C->data;
1769566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&c->ptapwork));
1779566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(c->ptapwork,A->rmap->n,P->cmap->n,A->rmap->N,P->cmap->N));
1789566063dSJacob Faibussowitsch   PetscCall(MatSetType(c->ptapwork,((PetscObject)C)->type_name));
1799566063dSJacob Faibussowitsch   PetscCall(MatSetUp(c->ptapwork));
180abc3b08eSStefano Zampini   PetscFunctionReturn(0);
181abc3b08eSStefano Zampini }
182abc3b08eSStefano Zampini 
183cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
184b49cda9fSStefano Zampini {
185a13144ffSStefano Zampini   Mat             B = NULL;
186b49cda9fSStefano Zampini   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
187b49cda9fSStefano Zampini   Mat_SeqDense    *b;
188b49cda9fSStefano Zampini   PetscInt        *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i;
1892e5835c6SStefano Zampini   const MatScalar *av;
190a13144ffSStefano Zampini   PetscBool       isseqdense;
191b49cda9fSStefano Zampini 
192b49cda9fSStefano Zampini   PetscFunctionBegin;
193a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
1949566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense));
19528b400f6SJacob Faibussowitsch     PetscCheck(isseqdense,PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type_name);
196a13144ffSStefano Zampini   }
197a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
1989566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
1999566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B,m,n,m,n));
2009566063dSJacob Faibussowitsch     PetscCall(MatSetType(B,MATSEQDENSE));
2019566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(B,NULL));
202b49cda9fSStefano Zampini     b    = (Mat_SeqDense*)(B->data);
203a13144ffSStefano Zampini   } else {
204a13144ffSStefano Zampini     b    = (Mat_SeqDense*)((*newmat)->data);
2059566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(b->v,m*n));
206a13144ffSStefano Zampini   }
2079566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJGetArrayRead(A,&av));
208b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
209b49cda9fSStefano Zampini     PetscInt j;
210b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
211b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
212b49cda9fSStefano Zampini       aj++;
213b49cda9fSStefano Zampini       av++;
214b49cda9fSStefano Zampini     }
215b49cda9fSStefano Zampini     ai++;
216b49cda9fSStefano Zampini   }
2179566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJRestoreArrayRead(A,&av));
218b49cda9fSStefano Zampini 
219511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2209566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
2219566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
2229566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A,&B));
223b49cda9fSStefano Zampini   } else {
224a13144ffSStefano Zampini     if (B) *newmat = B;
2259566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY));
2269566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY));
227b49cda9fSStefano Zampini   }
228b49cda9fSStefano Zampini   PetscFunctionReturn(0);
229b49cda9fSStefano Zampini }
230b49cda9fSStefano Zampini 
231cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
2326a63e612SBarry Smith {
2336d4ec7b0SPierre Jolivet   Mat            B = NULL;
2346a63e612SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2359399e1b8SMatthew G. Knepley   PetscInt       i, j;
2369399e1b8SMatthew G. Knepley   PetscInt       *rows, *nnz;
2379399e1b8SMatthew G. Knepley   MatScalar      *aa = a->v, *vals;
2386a63e612SBarry Smith 
2396a63e612SBarry Smith   PetscFunctionBegin;
2409566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals));
2416d4ec7b0SPierre Jolivet   if (reuse != MAT_REUSE_MATRIX) {
2429566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
2439566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N));
2449566063dSJacob Faibussowitsch     PetscCall(MatSetType(B,MATSEQAIJ));
2459399e1b8SMatthew G. Knepley     for (j=0; j<A->cmap->n; j++) {
2466d4ec7b0SPierre Jolivet       for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i];
2476a63e612SBarry Smith       aa += a->lda;
2486a63e612SBarry Smith     }
2499566063dSJacob Faibussowitsch     PetscCall(MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz));
2506d4ec7b0SPierre Jolivet   } else B = *newmat;
2519399e1b8SMatthew G. Knepley   aa = a->v;
2529399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2539399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2546d4ec7b0SPierre Jolivet     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) {rows[numRows] = i; vals[numRows++] = aa[i];}
2559566063dSJacob Faibussowitsch     PetscCall(MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES));
2569399e1b8SMatthew G. Knepley     aa  += a->lda;
2579399e1b8SMatthew G. Knepley   }
2589566063dSJacob Faibussowitsch   PetscCall(PetscFree3(rows,nnz,vals));
2599566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
2609566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
2616a63e612SBarry Smith 
262511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2639566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A,&B));
2646d4ec7b0SPierre Jolivet   } else if (reuse != MAT_REUSE_MATRIX) *newmat = B;
2656a63e612SBarry Smith   PetscFunctionReturn(0);
2666a63e612SBarry Smith }
2676a63e612SBarry Smith 
268ca15aa20SStefano Zampini PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
2691987afe7SBarry Smith {
2701987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
271ca15aa20SStefano Zampini   const PetscScalar *xv;
272ca15aa20SStefano Zampini   PetscScalar       *yv;
27323fff9afSBarry Smith   PetscBLASInt      N,m,ldax = 0,lday = 0,one = 1;
2743a40ed3dSBarry Smith 
2753a40ed3dSBarry Smith   PetscFunctionBegin;
2769566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(X,&xv));
2779566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(Y,&yv));
2789566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n*X->cmap->n,&N));
2799566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n,&m));
2809566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(x->lda,&ldax));
2819566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(y->lda,&lday));
282a5ce6ee0Svictorle   if (ldax>m || lday>m) {
283ca15aa20SStefano Zampini     PetscInt j;
284ca15aa20SStefano Zampini 
285d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
286ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&alpha,xv+j*ldax,&one,yv+j*lday,&one));
287a5ce6ee0Svictorle     }
288a5ce6ee0Svictorle   } else {
289ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&alpha,xv,&one,yv,&one));
290a5ce6ee0Svictorle   }
2919566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(X,&xv));
2929566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(Y,&yv));
2939566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(PetscMax(2.0*N-1,0)));
2943a40ed3dSBarry Smith   PetscFunctionReturn(0);
2951987afe7SBarry Smith }
2961987afe7SBarry Smith 
297e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
298289bc588SBarry Smith {
299ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n*A->cmap->n;
3003a40ed3dSBarry Smith 
3013a40ed3dSBarry Smith   PetscFunctionBegin;
3024e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
303ca15aa20SStefano Zampini   info->nz_allocated      = N;
304ca15aa20SStefano Zampini   info->nz_used           = N;
305ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
306ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
3074e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3087adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3094e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3104e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3114e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3123a40ed3dSBarry Smith   PetscFunctionReturn(0);
313289bc588SBarry Smith }
314289bc588SBarry Smith 
315637a0070SStefano Zampini PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
31680cd9d93SLois Curfman McInnes {
317273d9f13SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
318ca15aa20SStefano Zampini   PetscScalar    *v;
31923fff9afSBarry Smith   PetscBLASInt   one = 1,j,nz,lda = 0;
32080cd9d93SLois Curfman McInnes 
3213a40ed3dSBarry Smith   PetscFunctionBegin;
3229566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
3239566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(a->lda,&lda));
324d0f46423SBarry Smith   if (lda>A->rmap->n) {
3259566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n,&nz));
326d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
327ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v+j*lda,&one));
328a5ce6ee0Svictorle     }
329a5ce6ee0Svictorle   } else {
3309566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz));
331ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v,&one));
332a5ce6ee0Svictorle   }
33304cbc005SJose E. Roman   PetscCall(PetscLogFlops(A->rmap->n*A->cmap->n));
3349566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
3353a40ed3dSBarry Smith   PetscFunctionReturn(0);
33680cd9d93SLois Curfman McInnes }
33780cd9d93SLois Curfman McInnes 
3382f605a99SJose E. Roman PetscErrorCode MatShift_SeqDense(Mat A,PetscScalar alpha)
3392f605a99SJose E. Roman {
3402f605a99SJose E. Roman   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
3412f605a99SJose E. Roman   PetscScalar    *v;
3422f605a99SJose E. Roman   PetscInt       j,k;
3432f605a99SJose E. Roman 
3442f605a99SJose E. Roman   PetscFunctionBegin;
3452f605a99SJose E. Roman   PetscCall(MatDenseGetArray(A,&v));
3462f605a99SJose E. Roman   k = PetscMin(A->rmap->n,A->cmap->n);
3472f605a99SJose E. Roman   for (j=0; j<k; j++) v[j+j*a->lda] += alpha;
3482f605a99SJose E. Roman   PetscCall(PetscLogFlops(k));
3492f605a99SJose E. Roman   PetscCall(MatDenseRestoreArray(A,&v));
3502f605a99SJose E. Roman   PetscFunctionReturn(0);
3512f605a99SJose E. Roman }
3522f605a99SJose E. Roman 
353e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3541cbb95d3SBarry Smith {
3551cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
356ca15aa20SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
357ca15aa20SStefano Zampini   const PetscScalar *v;
3581cbb95d3SBarry Smith 
3591cbb95d3SBarry Smith   PetscFunctionBegin;
3601cbb95d3SBarry Smith   *fl = PETSC_FALSE;
361d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3629566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&v));
3631cbb95d3SBarry Smith   for (i=0; i<m; i++) {
364ca15aa20SStefano Zampini     for (j=i; j<m; j++) {
365637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) {
366637a0070SStefano Zampini         goto restore;
3671cbb95d3SBarry Smith       }
3681cbb95d3SBarry Smith     }
369637a0070SStefano Zampini   }
3701cbb95d3SBarry Smith   *fl  = PETSC_TRUE;
371637a0070SStefano Zampini restore:
3729566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&v));
373637a0070SStefano Zampini   PetscFunctionReturn(0);
374637a0070SStefano Zampini }
375637a0070SStefano Zampini 
376637a0070SStefano Zampini static PetscErrorCode MatIsSymmetric_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
377637a0070SStefano Zampini {
378637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
379637a0070SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
380637a0070SStefano Zampini   const PetscScalar *v;
381637a0070SStefano Zampini 
382637a0070SStefano Zampini   PetscFunctionBegin;
383637a0070SStefano Zampini   *fl = PETSC_FALSE;
384637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3859566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&v));
386637a0070SStefano Zampini   for (i=0; i<m; i++) {
387637a0070SStefano Zampini     for (j=i; j<m; j++) {
388637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - v[j+i*N]) > rtol) {
389637a0070SStefano Zampini         goto restore;
390637a0070SStefano Zampini       }
391637a0070SStefano Zampini     }
392637a0070SStefano Zampini   }
393637a0070SStefano Zampini   *fl  = PETSC_TRUE;
394637a0070SStefano Zampini restore:
3959566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&v));
3961cbb95d3SBarry Smith   PetscFunctionReturn(0);
3971cbb95d3SBarry Smith }
3981cbb95d3SBarry Smith 
399ca15aa20SStefano Zampini PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
400b24902e0SBarry Smith {
401ca15aa20SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
40223fc5dcaSStefano Zampini   PetscInt       lda = (PetscInt)mat->lda,j,m,nlda = lda;
40375f6d85dSStefano Zampini   PetscBool      isdensecpu;
404b24902e0SBarry Smith 
405b24902e0SBarry Smith   PetscFunctionBegin;
4069566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->rmap,&newi->rmap));
4079566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->cmap,&newi->cmap));
40823fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
4099566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(newi,lda));
41023fc5dcaSStefano Zampini   }
4119566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)newi,MATSEQDENSE,&isdensecpu));
4129566063dSJacob Faibussowitsch   if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi,NULL));
413b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
414ca15aa20SStefano Zampini     const PetscScalar *av;
415ca15aa20SStefano Zampini     PetscScalar       *v;
416ca15aa20SStefano Zampini 
4179566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A,&av));
4189566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayWrite(newi,&v));
4199566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(newi,&nlda));
420d0f46423SBarry Smith     m    = A->rmap->n;
42123fc5dcaSStefano Zampini     if (lda>m || nlda>m) {
422d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
4239566063dSJacob Faibussowitsch         PetscCall(PetscArraycpy(v+j*nlda,av+j*lda,m));
424b24902e0SBarry Smith       }
425b24902e0SBarry Smith     } else {
4269566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v,av,A->rmap->n*A->cmap->n));
427b24902e0SBarry Smith     }
4289566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayWrite(newi,&v));
4299566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A,&av));
430b24902e0SBarry Smith   }
431b24902e0SBarry Smith   PetscFunctionReturn(0);
432b24902e0SBarry Smith }
433b24902e0SBarry Smith 
434ca15aa20SStefano Zampini PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
43502cad45dSBarry Smith {
4363a40ed3dSBarry Smith   PetscFunctionBegin;
4379566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),newmat));
4389566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n));
4399566063dSJacob Faibussowitsch   PetscCall(MatSetType(*newmat,((PetscObject)A)->type_name));
4409566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues));
441b24902e0SBarry Smith   PetscFunctionReturn(0);
442b24902e0SBarry Smith }
443b24902e0SBarry Smith 
444bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
445289bc588SBarry Smith {
446c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4474396437dSToby Isaac   PetscBLASInt    info;
44867e560aaSBarry Smith 
4493a40ed3dSBarry Smith   PetscFunctionBegin;
4509566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
4514396437dSToby Isaac   PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_(T ? "T" : "N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
4529566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
45305fcb23eSStefano Zampini   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve %d",(int)info);
4549566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(2.0*m*m - m)));
4554396437dSToby Isaac   PetscFunctionReturn(0);
4564396437dSToby Isaac }
4574396437dSToby Isaac 
4584396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat);
4594396437dSToby Isaac 
460bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
4614396437dSToby Isaac {
4624396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4634396437dSToby Isaac   PetscBLASInt    info;
4644396437dSToby Isaac 
4654396437dSToby Isaac   PetscFunctionBegin;
466a49dc2a2SStefano Zampini   if (A->spd) {
4679566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
4689566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
4698b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
4709566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
47105fcb23eSStefano Zampini     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve %d",(int)info);
4729566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
473a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
474a49dc2a2SStefano Zampini   } else if (A->hermitian) {
4759566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
4769566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
477a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
4789566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
47905fcb23eSStefano Zampini     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve %d",(int)info);
4809566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
481a49dc2a2SStefano Zampini #endif
482a49dc2a2SStefano Zampini   } else { /* symmetric case */
4839566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
484a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
4859566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
48605fcb23eSStefano Zampini     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve %d",(int)info);
487a49dc2a2SStefano Zampini   }
4889566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(2.0*m*m - m)));
4894396437dSToby Isaac   PetscFunctionReturn(0);
4904396437dSToby Isaac }
49185e2c93fSHong Zhang 
492bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
4934396437dSToby Isaac {
4944396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4954396437dSToby Isaac   PetscBLASInt    info;
4964396437dSToby Isaac   char            trans;
4974396437dSToby Isaac 
4984396437dSToby Isaac   PetscFunctionBegin;
4994905a7bcSToby Isaac   if (PetscDefined(USE_COMPLEX)) {
5004905a7bcSToby Isaac     trans = 'C';
5014905a7bcSToby Isaac   } else {
5024905a7bcSToby Isaac     trans = 'T';
5034905a7bcSToby Isaac   }
5049566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
50505fcb23eSStefano Zampini   { /* lwork depends on the number of right-hand sides */
50605fcb23eSStefano Zampini     PetscBLASInt nlfwork, lfwork = -1;
50705fcb23eSStefano Zampini     PetscScalar  fwork;
50805fcb23eSStefano Zampini 
50905fcb23eSStefano Zampini     PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", &trans, &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,&fwork,&lfwork,&info));
51005fcb23eSStefano Zampini     nlfwork = (PetscBLASInt)PetscRealPart(fwork);
51105fcb23eSStefano Zampini     if (nlfwork > mat->lfwork) {
51205fcb23eSStefano Zampini       mat->lfwork = nlfwork;
51305fcb23eSStefano Zampini       PetscCall(PetscFree(mat->fwork));
51405fcb23eSStefano Zampini       PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
51505fcb23eSStefano Zampini     }
51605fcb23eSStefano Zampini   }
517bf5a80bcSToby Isaac   PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", &trans, &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,mat->fwork,&mat->lfwork,&info));
5189566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
51905fcb23eSStefano Zampini   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform %d",(int)info);
5209566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
521bf5a80bcSToby Isaac   PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "N", "N", &mat->rank,&nrhs,mat->v,&mat->lda,x,&ldx,&info));
5229566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
52305fcb23eSStefano Zampini   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve %d",(int)info);
5244905a7bcSToby Isaac   for (PetscInt j = 0; j < nrhs; j++) {
5254905a7bcSToby Isaac     for (PetscInt i = mat->rank; i < k; i++) {
526bf5a80bcSToby Isaac       x[j*ldx + i] = 0.;
5274905a7bcSToby Isaac     }
5284905a7bcSToby Isaac   }
5299566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank))));
5304905a7bcSToby Isaac   PetscFunctionReturn(0);
5314905a7bcSToby Isaac }
5324905a7bcSToby Isaac 
533bf5a80bcSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
5344905a7bcSToby Isaac {
5354396437dSToby Isaac   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
5364396437dSToby Isaac   PetscBLASInt      info;
5374396437dSToby Isaac 
5384396437dSToby Isaac   PetscFunctionBegin;
5394396437dSToby Isaac   if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
5409566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
541bf5a80bcSToby Isaac     PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "T", "N", &m,&nrhs,mat->v,&mat->lda,x,&ldx,&info));
5429566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
54305fcb23eSStefano Zampini     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve %d",(int)info);
5449566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
54505fcb23eSStefano Zampini     { /* lwork depends on the number of right-hand sides */
54605fcb23eSStefano Zampini       PetscBLASInt nlfwork, lfwork = -1;
54705fcb23eSStefano Zampini       PetscScalar  fwork;
54805fcb23eSStefano Zampini 
54905fcb23eSStefano Zampini       PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", "N", &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,&fwork,&lfwork,&info));
55005fcb23eSStefano Zampini       nlfwork = (PetscBLASInt)PetscRealPart(fwork);
55105fcb23eSStefano Zampini       if (nlfwork > mat->lfwork) {
55205fcb23eSStefano Zampini         mat->lfwork = nlfwork;
55305fcb23eSStefano Zampini         PetscCall(PetscFree(mat->fwork));
55405fcb23eSStefano Zampini         PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
55505fcb23eSStefano Zampini       }
55605fcb23eSStefano Zampini     }
5579566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
558bf5a80bcSToby Isaac     PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", "N", &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,mat->fwork,&mat->lfwork,&info));
5599566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
56005fcb23eSStefano Zampini     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform %d",(int)info);
5619566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
5624396437dSToby Isaac   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"QR factored matrix cannot be used for transpose solve");
5639566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank))));
5644396437dSToby Isaac   PetscFunctionReturn(0);
5654396437dSToby Isaac }
5664396437dSToby Isaac 
5674396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
5684396437dSToby Isaac {
5694396437dSToby Isaac   Mat_SeqDense      *mat = (Mat_SeqDense *) A->data;
5704905a7bcSToby Isaac   PetscScalar       *y;
5714905a7bcSToby Isaac   PetscBLASInt      m=0, k=0;
5724905a7bcSToby Isaac 
5734905a7bcSToby Isaac   PetscFunctionBegin;
5749566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
5759566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
5764905a7bcSToby Isaac   if (k < m) {
5779566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, mat->qrrhs));
5789566063dSJacob Faibussowitsch     PetscCall(VecGetArray(mat->qrrhs,&y));
5794905a7bcSToby Isaac   } else {
5809566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, yy));
5819566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy,&y));
5824905a7bcSToby Isaac   }
5834396437dSToby Isaac   *_y = y;
5844396437dSToby Isaac   *_k = k;
5854396437dSToby Isaac   *_m = m;
5864396437dSToby Isaac   PetscFunctionReturn(0);
5874396437dSToby Isaac }
5884396437dSToby Isaac 
5894396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
5904396437dSToby Isaac {
5914396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
59242e9364cSSatish Balay   PetscScalar    *y = NULL;
5934396437dSToby Isaac   PetscBLASInt   m, k;
5944396437dSToby Isaac 
5954396437dSToby Isaac   PetscFunctionBegin;
5964396437dSToby Isaac   y   = *_y;
5974396437dSToby Isaac   *_y = NULL;
5984396437dSToby Isaac   k   = *_k;
5994396437dSToby Isaac   m   = *_m;
6004905a7bcSToby Isaac   if (k < m) {
6014905a7bcSToby Isaac     PetscScalar *yv;
6029566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy,&yv));
6039566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(yv, y, k));
6049566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy,&yv));
6059566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(mat->qrrhs, &y));
6064905a7bcSToby Isaac   } else {
6079566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy,&y));
6084905a7bcSToby Isaac   }
6094905a7bcSToby Isaac   PetscFunctionReturn(0);
6104905a7bcSToby Isaac }
6114905a7bcSToby Isaac 
6124396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy)
6134396437dSToby Isaac {
61442e9364cSSatish Balay   PetscScalar    *y = NULL;
61542e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
6164396437dSToby Isaac 
6174396437dSToby Isaac   PetscFunctionBegin;
6189566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6199566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE));
6209566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6214396437dSToby Isaac   PetscFunctionReturn(0);
6224396437dSToby Isaac }
6234396437dSToby Isaac 
6244396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy)
6254396437dSToby Isaac {
62642e9364cSSatish Balay   PetscScalar    *y = NULL;
62742e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
6284396437dSToby Isaac 
6294396437dSToby Isaac   PetscFunctionBegin;
6309566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6319566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE));
6329566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6334396437dSToby Isaac   PetscFunctionReturn(0);
6344396437dSToby Isaac }
6354396437dSToby Isaac 
6364396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
6374396437dSToby Isaac {
638e54beecaSStefano Zampini   PetscScalar    *y = NULL;
639e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6404396437dSToby Isaac 
6414396437dSToby Isaac   PetscFunctionBegin;
6429566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6439566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE));
6449566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6454396437dSToby Isaac   PetscFunctionReturn(0);
6464396437dSToby Isaac }
6474396437dSToby Isaac 
6484396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
6494396437dSToby Isaac {
650e54beecaSStefano Zampini   PetscScalar    *y = NULL;
651e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6524396437dSToby Isaac 
6534396437dSToby Isaac   PetscFunctionBegin;
6549566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6559566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE));
6569566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6574396437dSToby Isaac   PetscFunctionReturn(0);
6584396437dSToby Isaac }
6594396437dSToby Isaac 
6604396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy)
6614396437dSToby Isaac {
662e54beecaSStefano Zampini   PetscScalar    *y = NULL;
663e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6644396437dSToby Isaac 
6654396437dSToby Isaac   PetscFunctionBegin;
6669566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6679566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k));
6689566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6694396437dSToby Isaac   PetscFunctionReturn(0);
6704396437dSToby Isaac }
6714396437dSToby Isaac 
6724396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy)
6734396437dSToby Isaac {
67442e9364cSSatish Balay   PetscScalar    *y = NULL;
67542e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
6764396437dSToby Isaac 
6774396437dSToby Isaac   PetscFunctionBegin;
6789566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6799566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k));
6809566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6814396437dSToby Isaac   PetscFunctionReturn(0);
6824396437dSToby Isaac }
6834396437dSToby Isaac 
684bf5a80bcSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
6854905a7bcSToby Isaac {
6864905a7bcSToby Isaac   const PetscScalar *b;
6874396437dSToby Isaac   PetscScalar       *y;
688bf5a80bcSToby Isaac   PetscInt          n, _ldb, _ldx;
689bf5a80bcSToby Isaac   PetscBLASInt      nrhs=0,m=0,k=0,ldb=0,ldx=0,ldy=0;
6904905a7bcSToby Isaac 
6914905a7bcSToby Isaac   PetscFunctionBegin;
6926280eecaSJose E. Roman   *_ldy=0; *_m=0; *_nrhs=0; *_k=0; *_y = NULL;
6939566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
6949566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
6959566063dSJacob Faibussowitsch   PetscCall(MatGetSize(B,NULL,&n));
6969566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n,&nrhs));
6979566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(B,&_ldb));
6989566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldb, &ldb));
6999566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X,&_ldx));
7009566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
701bf5a80bcSToby Isaac   if (ldx < m) {
7029566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(B,&b));
7039566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nrhs * m, &y));
704bf5a80bcSToby Isaac     if (ldb == m) {
7059566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(y,b,ldb*nrhs));
7064905a7bcSToby Isaac     } else {
7074905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
7089566063dSJacob Faibussowitsch         PetscCall(PetscArraycpy(&y[j*m],&b[j*ldb],m));
7094905a7bcSToby Isaac       }
7104905a7bcSToby Isaac     }
711bf5a80bcSToby Isaac     ldy = m;
7129566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(B,&b));
7134905a7bcSToby Isaac   } else {
714bf5a80bcSToby Isaac     if (ldb == ldx) {
7159566063dSJacob Faibussowitsch       PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN));
7169566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X,&y));
7174905a7bcSToby Isaac     } else {
7189566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X,&y));
7199566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArrayRead(B,&b));
7204905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
7219566063dSJacob Faibussowitsch         PetscCall(PetscArraycpy(&y[j*ldx],&b[j*ldb],m));
7224905a7bcSToby Isaac       }
7239566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArrayRead(B,&b));
7244905a7bcSToby Isaac     }
725bf5a80bcSToby Isaac     ldy = ldx;
7264905a7bcSToby Isaac   }
7274396437dSToby Isaac   *_y    = y;
728bf5a80bcSToby Isaac   *_ldy = ldy;
7294396437dSToby Isaac   *_k    = k;
7304396437dSToby Isaac   *_m    = m;
7314396437dSToby Isaac   *_nrhs = nrhs;
7324396437dSToby Isaac   PetscFunctionReturn(0);
7334396437dSToby Isaac }
7344396437dSToby Isaac 
735bf5a80bcSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
7364396437dSToby Isaac {
7374396437dSToby Isaac   PetscScalar       *y;
738bf5a80bcSToby Isaac   PetscInt          _ldx;
739bf5a80bcSToby Isaac   PetscBLASInt      k,ldy,nrhs,ldx=0;
7404396437dSToby Isaac 
7414396437dSToby Isaac   PetscFunctionBegin;
7424396437dSToby Isaac   y    = *_y;
7434396437dSToby Isaac   *_y  = NULL;
7444396437dSToby Isaac   k    = *_k;
745bf5a80bcSToby Isaac   ldy = *_ldy;
7464396437dSToby Isaac   nrhs = *_nrhs;
7479566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X,&_ldx));
7489566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
749bf5a80bcSToby Isaac   if (ldx != ldy) {
7504905a7bcSToby Isaac     PetscScalar *xv;
7519566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(X,&xv));
7524905a7bcSToby Isaac     for (PetscInt j = 0; j < nrhs; j++) {
7539566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(&xv[j*ldx],&y[j*ldy],k));
7544905a7bcSToby Isaac     }
7559566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X,&xv));
7569566063dSJacob Faibussowitsch     PetscCall(PetscFree(y));
7574905a7bcSToby Isaac   } else {
7589566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X,&y));
7594905a7bcSToby Isaac   }
76085e2c93fSHong Zhang   PetscFunctionReturn(0);
76185e2c93fSHong Zhang }
76285e2c93fSHong Zhang 
7634396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X)
7644396437dSToby Isaac {
7654396437dSToby Isaac   PetscScalar    *y;
766bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7674396437dSToby Isaac 
7684396437dSToby Isaac   PetscFunctionBegin;
7699566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7709566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7719566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7724396437dSToby Isaac   PetscFunctionReturn(0);
7734396437dSToby Isaac }
7744396437dSToby Isaac 
7754396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X)
7764396437dSToby Isaac {
7774396437dSToby Isaac   PetscScalar    *y;
778bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7794396437dSToby Isaac 
7804396437dSToby Isaac   PetscFunctionBegin;
7819566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7829566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7839566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7844396437dSToby Isaac   PetscFunctionReturn(0);
7854396437dSToby Isaac }
7864396437dSToby Isaac 
7874396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X)
7884396437dSToby Isaac {
7894396437dSToby Isaac   PetscScalar    *y;
790bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7914396437dSToby Isaac 
7924396437dSToby Isaac   PetscFunctionBegin;
7939566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7949566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7959566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7964396437dSToby Isaac   PetscFunctionReturn(0);
7974396437dSToby Isaac }
7984396437dSToby Isaac 
7994396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X)
8004396437dSToby Isaac {
8014396437dSToby Isaac   PetscScalar    *y;
802bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
8034396437dSToby Isaac 
8044396437dSToby Isaac   PetscFunctionBegin;
8059566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
8069566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE));
8079566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
8084396437dSToby Isaac   PetscFunctionReturn(0);
8094396437dSToby Isaac }
8104396437dSToby Isaac 
8114396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X)
8124396437dSToby Isaac {
8134396437dSToby Isaac   PetscScalar    *y;
814bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
8154396437dSToby Isaac 
8164396437dSToby Isaac   PetscFunctionBegin;
8179566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
8189566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
8199566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
8204396437dSToby Isaac   PetscFunctionReturn(0);
8214396437dSToby Isaac }
8224396437dSToby Isaac 
8234396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X)
8244396437dSToby Isaac {
8254396437dSToby Isaac   PetscScalar    *y;
826bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
8274396437dSToby Isaac 
8284396437dSToby Isaac   PetscFunctionBegin;
8299566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
8309566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
8319566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
8324396437dSToby Isaac   PetscFunctionReturn(0);
8334396437dSToby Isaac }
8344396437dSToby Isaac 
835db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
836db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
837db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
838ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
839db4efbfdSBarry Smith {
840db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
841db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
842db4efbfdSBarry Smith 
843db4efbfdSBarry Smith   PetscFunctionBegin;
8449566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
8459566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
846db4efbfdSBarry Smith   if (!mat->pivots) {
8479566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots));
8489566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt)));
849db4efbfdSBarry Smith   }
850db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
8519566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
8528b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
8539566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
8548e57ea43SSatish Balay 
85505fcb23eSStefano Zampini   PetscCheck(info>=0,PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization %d",(int)info);
85605fcb23eSStefano Zampini   PetscCheck(info<=0,PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization %d",(int)info);
8578208b9aeSStefano Zampini 
8584396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
8594396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
8604396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8614396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
862d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
863db4efbfdSBarry Smith 
8649566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8659566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype));
866f6224b95SHong Zhang 
8679566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3));
868db4efbfdSBarry Smith   PetscFunctionReturn(0);
869db4efbfdSBarry Smith }
870db4efbfdSBarry Smith 
8714396437dSToby Isaac static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
8724396437dSToby Isaac {
8734396437dSToby Isaac   MatFactorInfo  info;
8744396437dSToby Isaac 
8754396437dSToby Isaac   PetscFunctionBegin;
8769566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES));
8779566063dSJacob Faibussowitsch   PetscCall((*fact->ops->lufactor)(fact,NULL,NULL,&info));
8784396437dSToby Isaac   PetscFunctionReturn(0);
8794396437dSToby Isaac }
8804396437dSToby Isaac 
8814396437dSToby Isaac PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
8824396437dSToby Isaac {
8834396437dSToby Isaac   PetscFunctionBegin;
8844396437dSToby Isaac   fact->preallocated           = PETSC_TRUE;
8854396437dSToby Isaac   fact->assembled              = PETSC_TRUE;
8864396437dSToby Isaac   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
8874396437dSToby Isaac   PetscFunctionReturn(0);
8884396437dSToby Isaac }
8894396437dSToby Isaac 
890a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
891ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
892db4efbfdSBarry Smith {
893db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
894c5df96a5SBarry Smith   PetscBLASInt   info,n;
895db4efbfdSBarry Smith 
896db4efbfdSBarry Smith   PetscFunctionBegin;
8979566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
898db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
899a49dc2a2SStefano Zampini   if (A->spd) {
9009566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
9018b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
9029566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
903a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
904a49dc2a2SStefano Zampini   } else if (A->hermitian) {
905a49dc2a2SStefano Zampini     if (!mat->pivots) {
9069566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots));
9079566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt)));
908a49dc2a2SStefano Zampini     }
909a49dc2a2SStefano Zampini     if (!mat->fwork) {
910a49dc2a2SStefano Zampini       PetscScalar dummy;
911a49dc2a2SStefano Zampini 
912a49dc2a2SStefano Zampini       mat->lfwork = -1;
9139566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
914a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
9159566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
916a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
9179566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
9189566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
919a49dc2a2SStefano Zampini     }
9209566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
921a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
9229566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
923a49dc2a2SStefano Zampini #endif
924a49dc2a2SStefano Zampini   } else { /* symmetric case */
925a49dc2a2SStefano Zampini     if (!mat->pivots) {
9269566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots));
9279566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt)));
928a49dc2a2SStefano Zampini     }
929a49dc2a2SStefano Zampini     if (!mat->fwork) {
930a49dc2a2SStefano Zampini       PetscScalar dummy;
931a49dc2a2SStefano Zampini 
932a49dc2a2SStefano Zampini       mat->lfwork = -1;
9339566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
934a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
9359566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
936a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
9379566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
9389566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
939a49dc2a2SStefano Zampini     }
9409566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
941a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
9429566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
943a49dc2a2SStefano Zampini   }
94428b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %" PetscInt_FMT,(PetscInt)info-1);
9458208b9aeSStefano Zampini 
9464396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
9474396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
9484396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
9494396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
950d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
9512205254eSKarl Rupp 
9529566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9539566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype));
954f6224b95SHong Zhang 
9559566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0));
956db4efbfdSBarry Smith   PetscFunctionReturn(0);
957db4efbfdSBarry Smith }
958db4efbfdSBarry Smith 
9594396437dSToby Isaac static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
960db4efbfdSBarry Smith {
961db4efbfdSBarry Smith   MatFactorInfo  info;
962db4efbfdSBarry Smith 
963db4efbfdSBarry Smith   PetscFunctionBegin;
964db4efbfdSBarry Smith   info.fill = 1.0;
9652205254eSKarl Rupp 
9669566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES));
9679566063dSJacob Faibussowitsch   PetscCall((*fact->ops->choleskyfactor)(fact,NULL,&info));
968db4efbfdSBarry Smith   PetscFunctionReturn(0);
969db4efbfdSBarry Smith }
970db4efbfdSBarry Smith 
971ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
972db4efbfdSBarry Smith {
973db4efbfdSBarry Smith   PetscFunctionBegin;
974c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9751bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
976719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
977db4efbfdSBarry Smith   PetscFunctionReturn(0);
978db4efbfdSBarry Smith }
979db4efbfdSBarry Smith 
980bf5a80bcSToby Isaac PetscErrorCode MatQRFactor_SeqDense(Mat A,IS col,const MatFactorInfo *minfo)
9814905a7bcSToby Isaac {
9824905a7bcSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
9834905a7bcSToby Isaac   PetscBLASInt   n,m,info, min, max;
9844905a7bcSToby Isaac 
9854905a7bcSToby Isaac   PetscFunctionBegin;
9869566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
9879566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
9884396437dSToby Isaac   max = PetscMax(m, n);
9894396437dSToby Isaac   min = PetscMin(m, n);
9904905a7bcSToby Isaac   if (!mat->tau) {
9919566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(min,&mat->tau));
9929566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,min*sizeof(PetscScalar)));
9934396437dSToby Isaac   }
9944396437dSToby Isaac   if (!mat->pivots) {
9959566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&mat->pivots));
9969566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,n*sizeof(PetscScalar)));
9974396437dSToby Isaac   }
9984396437dSToby Isaac   if (!mat->qrrhs) {
9999566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs)));
10004905a7bcSToby Isaac   }
10014905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
10024905a7bcSToby Isaac   if (!mat->fwork) {
10034905a7bcSToby Isaac     PetscScalar dummy;
10044905a7bcSToby Isaac 
10054905a7bcSToby Isaac     mat->lfwork = -1;
10069566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
10074905a7bcSToby Isaac     PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,&dummy,&mat->lfwork,&info));
10089566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
10094905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
10109566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
10119566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
10124905a7bcSToby Isaac   }
10139566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
10144905a7bcSToby Isaac   PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,mat->fwork,&mat->lfwork,&info));
10159566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
101605fcb23eSStefano Zampini   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to QR factorization %d",(int)info);
10174905a7bcSToby Isaac   // TODO: try to estimate rank or test for and use geqp3 for rank revealing QR.  For now just say rank is min of m and n
10184905a7bcSToby Isaac   mat->rank = min;
10194905a7bcSToby Isaac 
10204396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_QR;
10214396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_QR;
10224905a7bcSToby Isaac   A->factortype             = MAT_FACTOR_QR;
10234905a7bcSToby Isaac   if (m == n) {
10244396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
10254396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
10264905a7bcSToby Isaac   }
10274905a7bcSToby Isaac 
10289566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
10299566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype));
10304905a7bcSToby Isaac 
10319566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0*min*min*(max-min/3.0)));
10324905a7bcSToby Isaac   PetscFunctionReturn(0);
10334905a7bcSToby Isaac }
10344905a7bcSToby Isaac 
10354905a7bcSToby Isaac static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
10364905a7bcSToby Isaac {
10374905a7bcSToby Isaac   MatFactorInfo  info;
10384905a7bcSToby Isaac 
10394905a7bcSToby Isaac   PetscFunctionBegin;
10404905a7bcSToby Isaac   info.fill = 1.0;
10414905a7bcSToby Isaac 
10429566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES));
1043cac4c232SBarry Smith   PetscUseMethod(fact,"MatQRFactor_C",(Mat,IS,const MatFactorInfo *),(fact,NULL,&info));
10444905a7bcSToby Isaac   PetscFunctionReturn(0);
10454905a7bcSToby Isaac }
10464905a7bcSToby Isaac 
1047bf5a80bcSToby Isaac PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
10484905a7bcSToby Isaac {
10494905a7bcSToby Isaac   PetscFunctionBegin;
10504905a7bcSToby Isaac   fact->assembled                  = PETSC_TRUE;
10514905a7bcSToby Isaac   fact->preallocated               = PETSC_TRUE;
10529566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fact,"MatQRFactorNumeric_C",MatQRFactorNumeric_SeqDense));
10534905a7bcSToby Isaac   PetscFunctionReturn(0);
10544905a7bcSToby Isaac }
10554905a7bcSToby Isaac 
1056ca15aa20SStefano Zampini /* uses LAPACK */
1057cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
1058db4efbfdSBarry Smith {
1059db4efbfdSBarry Smith   PetscFunctionBegin;
10609566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),fact));
10619566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n));
10629566063dSJacob Faibussowitsch   PetscCall(MatSetType(*fact,MATDENSE));
106366e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
10642a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
1065db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
10662a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
1067bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) {
1068db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
1069bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_QR) {
10709566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)(*fact),"MatQRFactorSymbolic_C",MatQRFactorSymbolic_SeqDense));
1071db4efbfdSBarry Smith   }
1072d5f3da31SBarry Smith   (*fact)->factortype = ftype;
107300c67f3bSHong Zhang 
10749566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fact)->solvertype));
10759566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype));
10769566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_LU]));
10779566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ILU]));
10789566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]));
10799566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ICC]));
1080db4efbfdSBarry Smith   PetscFunctionReturn(0);
1081db4efbfdSBarry Smith }
1082db4efbfdSBarry Smith 
1083289bc588SBarry Smith /* ------------------------------------------------------------------*/
1084e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
1085289bc588SBarry Smith {
1086c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1087d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
1088d9ca1df4SBarry Smith   const PetscScalar *b;
1089d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
109023fff9afSBarry Smith   PetscBLASInt      o = 1,bm = 0;
1091289bc588SBarry Smith 
10923a40ed3dSBarry Smith   PetscFunctionBegin;
1093ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
109408401ef6SPierre Jolivet   PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
1095ca15aa20SStefano Zampini #endif
1096422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
10979566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m,&bm));
1098289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
10993bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
11009566063dSJacob Faibussowitsch     PetscCall(VecSet(xx,zero));
1101289bc588SBarry Smith   }
11029566063dSJacob Faibussowitsch   PetscCall(VecGetArray(xx,&x));
11039566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(bb,&b));
1104b965ef7fSBarry Smith   its  = its*lits;
110508401ef6SPierre Jolivet   PetscCheck(its > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %" PetscInt_FMT " and local its %" PetscInt_FMT " both positive",its,lits);
1106289bc588SBarry Smith   while (its--) {
1107fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1108289bc588SBarry Smith       for (i=0; i<m; i++) {
11093bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
111055a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1111289bc588SBarry Smith       }
1112289bc588SBarry Smith     }
1113fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1114289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
11153bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
111655a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1117289bc588SBarry Smith       }
1118289bc588SBarry Smith     }
1119289bc588SBarry Smith   }
11209566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(bb,&b));
11219566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(xx,&x));
11223a40ed3dSBarry Smith   PetscFunctionReturn(0);
1123289bc588SBarry Smith }
1124289bc588SBarry Smith 
1125289bc588SBarry Smith /* -----------------------------------------------------------------*/
1126ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
1127289bc588SBarry Smith {
1128c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1129d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
1130d9ca1df4SBarry Smith   PetscScalar       *y;
11310805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
1132ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
11333a40ed3dSBarry Smith 
11343a40ed3dSBarry Smith   PetscFunctionBegin;
11359566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
11369566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11379566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11389566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy,&y));
11395ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11405ac36cfcSBarry Smith     PetscBLASInt i;
11415ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
11425ac36cfcSBarry Smith   } else {
11438b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
11449566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n));
11455ac36cfcSBarry Smith   }
11469566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11479566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy,&y));
11483a40ed3dSBarry Smith   PetscFunctionReturn(0);
1149289bc588SBarry Smith }
1150800995b7SMatthew Knepley 
1151ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
1152289bc588SBarry Smith {
1153c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1154d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
11550805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
1156d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
11573a40ed3dSBarry Smith 
11583a40ed3dSBarry Smith   PetscFunctionBegin;
11599566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
11609566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11619566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11629566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy,&y));
11635ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11645ac36cfcSBarry Smith     PetscBLASInt i;
11655ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
11665ac36cfcSBarry Smith   } else {
11678b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
11689566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n));
11695ac36cfcSBarry Smith   }
11709566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11719566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy,&y));
11723a40ed3dSBarry Smith   PetscFunctionReturn(0);
1173289bc588SBarry Smith }
11746ee01492SSatish Balay 
1175ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1176289bc588SBarry Smith {
1177c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1178d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1179d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
11800805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
11813a40ed3dSBarry Smith 
11823a40ed3dSBarry Smith   PetscFunctionBegin;
11839566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
11849566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11859566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz,yy));
1186d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11879566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11889566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy,&y));
11898b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
11909566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11919566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy,&y));
11929566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n));
11933a40ed3dSBarry Smith   PetscFunctionReturn(0);
1194289bc588SBarry Smith }
11956ee01492SSatish Balay 
1196ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1197289bc588SBarry Smith {
1198c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1199d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1200d9ca1df4SBarry Smith   PetscScalar       *y;
12010805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
120287828ca2SBarry Smith   PetscScalar       _DOne=1.0;
12033a40ed3dSBarry Smith 
12043a40ed3dSBarry Smith   PetscFunctionBegin;
12059566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
12069566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
12079566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz,yy));
1208d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
12099566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
12109566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy,&y));
12118b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
12129566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
12139566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy,&y));
12149566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n));
12153a40ed3dSBarry Smith   PetscFunctionReturn(0);
1216289bc588SBarry Smith }
1217289bc588SBarry Smith 
1218289bc588SBarry Smith /* -----------------------------------------------------------------*/
1219e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1220289bc588SBarry Smith {
1221c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
122213f74950SBarry Smith   PetscInt       i;
122367e560aaSBarry Smith 
12243a40ed3dSBarry Smith   PetscFunctionBegin;
1225d0f46423SBarry Smith   *ncols = A->cmap->n;
1226289bc588SBarry Smith   if (cols) {
12279566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n,cols));
1228d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
1229289bc588SBarry Smith   }
1230289bc588SBarry Smith   if (vals) {
1231ca15aa20SStefano Zampini     const PetscScalar *v;
1232ca15aa20SStefano Zampini 
12339566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A,&v));
12349566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n,vals));
1235ca15aa20SStefano Zampini     v   += row;
1236d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
12379566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A,&v));
1238289bc588SBarry Smith   }
12393a40ed3dSBarry Smith   PetscFunctionReturn(0);
1240289bc588SBarry Smith }
12416ee01492SSatish Balay 
1242e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1243289bc588SBarry Smith {
1244606d414cSSatish Balay   PetscFunctionBegin;
1245cb4a9cd9SHong Zhang   if (ncols) *ncols = 0;
12469566063dSJacob Faibussowitsch   if (cols) PetscCall(PetscFree(*cols));
12479566063dSJacob Faibussowitsch   if (vals) PetscCall(PetscFree(*vals));
12483a40ed3dSBarry Smith   PetscFunctionReturn(0);
1249289bc588SBarry Smith }
1250289bc588SBarry Smith /* ----------------------------------------------------------------*/
1251e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
1252289bc588SBarry Smith {
1253c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
1254ca15aa20SStefano Zampini   PetscScalar      *av;
125513f74950SBarry Smith   PetscInt         i,j,idx=0;
1256ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1257c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1258ca15aa20SStefano Zampini #endif
1259d6dfbf8fSBarry Smith 
12603a40ed3dSBarry Smith   PetscFunctionBegin;
12619566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&av));
1262289bc588SBarry Smith   if (!mat->roworiented) {
1263dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1264289bc588SBarry Smith       for (j=0; j<n; j++) {
1265cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
12666bdcaf15SBarry Smith         PetscCheck(indexn[j] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT,indexn[j],A->cmap->n-1);
1267289bc588SBarry Smith         for (i=0; i<m; i++) {
1268cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
12696bdcaf15SBarry Smith           PetscCheck(indexm[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT,indexm[i],A->rmap->n-1);
1270ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1271289bc588SBarry Smith         }
1272289bc588SBarry Smith       }
12733a40ed3dSBarry Smith     } else {
1274289bc588SBarry Smith       for (j=0; j<n; j++) {
1275cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
12766bdcaf15SBarry Smith         PetscCheck(indexn[j] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT,indexn[j],A->cmap->n-1);
1277289bc588SBarry Smith         for (i=0; i<m; i++) {
1278cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
12796bdcaf15SBarry Smith           PetscCheck(indexm[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT,indexm[i],A->rmap->n-1);
1280ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1281289bc588SBarry Smith         }
1282289bc588SBarry Smith       }
1283289bc588SBarry Smith     }
12843a40ed3dSBarry Smith   } else {
1285dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1286e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
1287cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
12886bdcaf15SBarry Smith         PetscCheck(indexm[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT,indexm[i],A->rmap->n-1);
1289e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
1290cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
12916bdcaf15SBarry Smith           PetscCheck(indexn[j] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT,indexn[j],A->cmap->n-1);
1292ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1293e8d4e0b9SBarry Smith         }
1294e8d4e0b9SBarry Smith       }
12953a40ed3dSBarry Smith     } else {
1296289bc588SBarry Smith       for (i=0; i<m; i++) {
1297cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
12986bdcaf15SBarry Smith         PetscCheck(indexm[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT,indexm[i],A->rmap->n-1);
1299289bc588SBarry Smith         for (j=0; j<n; j++) {
1300cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
13016bdcaf15SBarry Smith           PetscCheck(indexn[j] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT,indexn[j],A->cmap->n-1);
1302ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1303289bc588SBarry Smith         }
1304289bc588SBarry Smith       }
1305289bc588SBarry Smith     }
1306e8d4e0b9SBarry Smith   }
1307ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
1308ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1309c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
1310c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1311ca15aa20SStefano Zampini #endif
13129566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&av));
1313ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1314c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1315ca15aa20SStefano Zampini #endif
13163a40ed3dSBarry Smith   PetscFunctionReturn(0);
1317289bc588SBarry Smith }
1318e8d4e0b9SBarry Smith 
1319e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1320ae80bb75SLois Curfman McInnes {
1321ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1322ca15aa20SStefano Zampini   const PetscScalar *vv;
132313f74950SBarry Smith   PetscInt          i,j;
1324ae80bb75SLois Curfman McInnes 
13253a40ed3dSBarry Smith   PetscFunctionBegin;
13269566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&vv));
1327ae80bb75SLois Curfman McInnes   /* row-oriented output */
1328ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
132997e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
133008401ef6SPierre Jolivet     PetscCheck(indexm[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %" PetscInt_FMT " requested larger than number rows %" PetscInt_FMT,indexm[i],A->rmap->n);
1331ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
13326f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
133308401ef6SPierre Jolivet       PetscCheck(indexn[j] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column %" PetscInt_FMT " requested larger than number columns %" PetscInt_FMT,indexn[j],A->cmap->n);
1334ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1335ae80bb75SLois Curfman McInnes     }
1336ae80bb75SLois Curfman McInnes   }
13379566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&vv));
13383a40ed3dSBarry Smith   PetscFunctionReturn(0);
1339ae80bb75SLois Curfman McInnes }
1340ae80bb75SLois Curfman McInnes 
1341289bc588SBarry Smith /* -----------------------------------------------------------------*/
1342289bc588SBarry Smith 
13438491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1344aabbc4fbSShri Abhyankar {
13458491ab44SLisandro Dalcin   PetscBool         skipHeader;
13468491ab44SLisandro Dalcin   PetscViewerFormat format;
13478491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
13488491ab44SLisandro Dalcin   const PetscScalar *v;
13498491ab44SLisandro Dalcin   PetscScalar       *vwork;
1350aabbc4fbSShri Abhyankar 
1351aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13529566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13539566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader));
13549566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer,&format));
13558491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1356aabbc4fbSShri Abhyankar 
13579566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat,&M,&N));
13588491ab44SLisandro Dalcin 
13598491ab44SLisandro Dalcin   /* write matrix header */
13608491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
13618491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
13629566063dSJacob Faibussowitsch   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer,header,4,PETSC_INT));
13638491ab44SLisandro Dalcin 
13649566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat,&m,NULL));
13658491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13668491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
13678491ab44SLisandro Dalcin     /* store row lengths for each row */
13689566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz,&iwork));
13698491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
13709566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
13718491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13728491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
13738491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
13748491ab44SLisandro Dalcin         iwork[k] = j;
13759566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
13769566063dSJacob Faibussowitsch     PetscCall(PetscFree(iwork));
13778491ab44SLisandro Dalcin   }
13788491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13799566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(m*N,&vwork));
13809566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(mat,&v));
13819566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat,&lda));
13828491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
13838491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
13848491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
13859566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(mat,&v));
13869566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR));
13879566063dSJacob Faibussowitsch   PetscCall(PetscFree(vwork));
13888491ab44SLisandro Dalcin   PetscFunctionReturn(0);
13898491ab44SLisandro Dalcin }
13908491ab44SLisandro Dalcin 
13918491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
13928491ab44SLisandro Dalcin {
13938491ab44SLisandro Dalcin   PetscBool      skipHeader;
13948491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
13958491ab44SLisandro Dalcin   PetscInt       rows,cols;
13968491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
13978491ab44SLisandro Dalcin 
13988491ab44SLisandro Dalcin   PetscFunctionBegin;
13999566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14009566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader));
14018491ab44SLisandro Dalcin 
14028491ab44SLisandro Dalcin   if (!skipHeader) {
14039566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT));
140408401ef6SPierre Jolivet     PetscCheck(header[0] == MAT_FILE_CLASSID,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
14058491ab44SLisandro Dalcin     M = header[1]; N = header[2];
140608401ef6SPierre Jolivet     PetscCheck(M >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%" PetscInt_FMT ") in file is negative",M);
140708401ef6SPierre Jolivet     PetscCheck(N >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%" PetscInt_FMT ") in file is negative",N);
14088491ab44SLisandro Dalcin     nz = header[3];
1409aed4548fSBarry Smith     PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %" PetscInt_FMT " in file",nz);
1410aabbc4fbSShri Abhyankar   } else {
14119566063dSJacob Faibussowitsch     PetscCall(MatGetSize(mat,&M,&N));
1412aed4548fSBarry Smith     PetscCheck(M >= 0 && N >= 0,PETSC_COMM_SELF,PETSC_ERR_USER,"Matrix binary file header was skipped, thus the user must specify the global sizes of input matrix");
14138491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1414e6324fbbSBarry Smith   }
1415aabbc4fbSShri Abhyankar 
14168491ab44SLisandro Dalcin   /* setup global sizes if not set */
14178491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
14188491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
14199566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat));
14208491ab44SLisandro Dalcin   /* check if global sizes are correct */
14219566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat,&rows,&cols));
1422aed4548fSBarry Smith   PetscCheck(M == rows && N == cols,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different sizes (%" PetscInt_FMT ", %" PetscInt_FMT ") than the input matrix (%" PetscInt_FMT ", %" PetscInt_FMT ")",M,N,rows,cols);
1423aabbc4fbSShri Abhyankar 
14249566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat,NULL,&N));
14259566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat,&m,NULL));
14269566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(mat,&v));
14279566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat,&lda));
14288491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
14298491ab44SLisandro Dalcin     PetscInt nnz = m*N;
14308491ab44SLisandro Dalcin     /* read in matrix values */
14319566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz,&vwork));
14329566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR));
14338491ab44SLisandro Dalcin     /* store values in column major order */
14348491ab44SLisandro Dalcin     for (j=0; j<N; j++)
14358491ab44SLisandro Dalcin       for (i=0; i<m; i++)
14368491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
14379566063dSJacob Faibussowitsch     PetscCall(PetscFree(vwork));
14388491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14398491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14408491ab44SLisandro Dalcin     /* read in row lengths */
14419566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m,&rlens));
14429566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
14438491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
14448491ab44SLisandro Dalcin     /* read in column indices and values */
14459566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(nnz,&icols,nnz,&vwork));
14469566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
14479566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR));
14488491ab44SLisandro Dalcin     /* store values in column major order */
14498491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
14508491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
14518491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
14529566063dSJacob Faibussowitsch     PetscCall(PetscFree(rlens));
14539566063dSJacob Faibussowitsch     PetscCall(PetscFree2(icols,vwork));
1454aabbc4fbSShri Abhyankar   }
14559566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(mat,&v));
14569566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY));
14579566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY));
1458aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1459aabbc4fbSShri Abhyankar }
1460aabbc4fbSShri Abhyankar 
1461eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1462eb91f321SVaclav Hapla {
1463eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1464eb91f321SVaclav Hapla 
1465eb91f321SVaclav Hapla   PetscFunctionBegin;
1466eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1467eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1468eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
14699566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14709566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
14719566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5));
1472eb91f321SVaclav Hapla   if (isbinary) {
14739566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_Binary(newMat,viewer));
1474eb91f321SVaclav Hapla   } else if (ishdf5) {
1475eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
14769566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_HDF5(newMat,viewer));
1477eb91f321SVaclav Hapla #else
1478eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1479eb91f321SVaclav Hapla #endif
1480eb91f321SVaclav Hapla   } else {
148198921bdaSJacob Faibussowitsch     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"Viewer type %s not yet supported for reading %s matrices",((PetscObject)viewer)->type_name,((PetscObject)newMat)->type_name);
1482eb91f321SVaclav Hapla   }
1483eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1484eb91f321SVaclav Hapla }
1485eb91f321SVaclav Hapla 
14866849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1487289bc588SBarry Smith {
1488932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
148913f74950SBarry Smith   PetscInt          i,j;
14902dcb1b2aSMatthew Knepley   const char        *name;
1491ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1492f3ef73ceSBarry Smith   PetscViewerFormat format;
14935f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1494ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
14955f481a85SSatish Balay #endif
1496932b0c3eSLois Curfman McInnes 
14973a40ed3dSBarry Smith   PetscFunctionBegin;
14989566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&av));
14999566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer,&format));
1500456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
15013a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1502fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
15039566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
1504d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1505ca15aa20SStefano Zampini       v    = av + i;
15069566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"row %" PetscInt_FMT ":",i));
1507d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1508aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1509329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
15109566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v)));
1511329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
15129566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",j,(double)PetscRealPart(*v)));
15136831982aSBarry Smith         }
151480cd9d93SLois Curfman McInnes #else
15156831982aSBarry Smith         if (*v) {
15169566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",j,(double)*v));
15176831982aSBarry Smith         }
151880cd9d93SLois Curfman McInnes #endif
15191b807ce4Svictorle         v += a->lda;
152080cd9d93SLois Curfman McInnes       }
15219566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
152280cd9d93SLois Curfman McInnes     }
15239566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
15243a40ed3dSBarry Smith   } else {
15259566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
1526aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
152747989497SBarry Smith     /* determine if matrix has all real values */
1528bcd8d3a4SJose E. Roman     for (j=0; j<A->cmap->n; j++) {
1529bcd8d3a4SJose E. Roman       v = av + j*a->lda;
1530bcd8d3a4SJose E. Roman       for (i=0; i<A->rmap->n; i++) {
1531ffac6cdbSBarry Smith         if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
153247989497SBarry Smith       }
1533bcd8d3a4SJose E. Roman     }
153447989497SBarry Smith #endif
1535fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15369566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName((PetscObject)A,&name));
15379566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n",A->rmap->n,A->cmap->n));
15389566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n",name,A->rmap->n,A->cmap->n));
15399566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%s = [\n",name));
1540ffac6cdbSBarry Smith     }
1541ffac6cdbSBarry Smith 
1542d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1543ca15aa20SStefano Zampini       v = av + i;
1544d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1545aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
154647989497SBarry Smith         if (allreal) {
15479566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v)));
154847989497SBarry Smith         } else {
15499566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v)));
155047989497SBarry Smith         }
1551289bc588SBarry Smith #else
15529566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v));
1553289bc588SBarry Smith #endif
15541b807ce4Svictorle         v += a->lda;
1555289bc588SBarry Smith       }
15569566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
1557289bc588SBarry Smith     }
1558fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15599566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"];\n"));
1560ffac6cdbSBarry Smith     }
15619566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
1562da3a660dSBarry Smith   }
15639566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&av));
15649566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
15653a40ed3dSBarry Smith   PetscFunctionReturn(0);
1566289bc588SBarry Smith }
1567289bc588SBarry Smith 
15689804daf3SBarry Smith #include <petscdraw.h>
1569e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1570f1af5d2fSBarry Smith {
1571f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
1572383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1573383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1574ca15aa20SStefano Zampini   const PetscScalar *v;
1575b0a32e0cSBarry Smith   PetscViewer       viewer;
1576b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1577f3ef73ceSBarry Smith   PetscViewerFormat format;
1578f1af5d2fSBarry Smith 
1579f1af5d2fSBarry Smith   PetscFunctionBegin;
15809566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer));
15819566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer,&format));
15829566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr));
1583f1af5d2fSBarry Smith 
1584f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
15859566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&v));
1586fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1587d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1588f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1589f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1590383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1591f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1592f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1593f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1594ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1595ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1596ca15aa20SStefano Zampini         else continue;
15979566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color));
1598f1af5d2fSBarry Smith       }
1599f1af5d2fSBarry Smith     }
1600d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1601f1af5d2fSBarry Smith   } else {
1602f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1603f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1604b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1605b05fc000SLisandro Dalcin     PetscDraw popup;
1606b05fc000SLisandro Dalcin 
1607f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1608f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1609f1af5d2fSBarry Smith     }
1610383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
16119566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetPopup(draw,&popup));
16129566063dSJacob Faibussowitsch     PetscCall(PetscDrawScalePopup(popup,minv,maxv));
1613383922c3SLisandro Dalcin 
1614d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1615f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1616f1af5d2fSBarry Smith       x_l = j;
1617f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1618f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1619f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1620f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1621b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
16229566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color));
1623f1af5d2fSBarry Smith       }
1624f1af5d2fSBarry Smith     }
1625d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1626f1af5d2fSBarry Smith   }
16279566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&v));
1628f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1629f1af5d2fSBarry Smith }
1630f1af5d2fSBarry Smith 
1631e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1632f1af5d2fSBarry Smith {
1633b0a32e0cSBarry Smith   PetscDraw      draw;
1634ace3abfcSBarry Smith   PetscBool      isnull;
1635329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1636f1af5d2fSBarry Smith 
1637f1af5d2fSBarry Smith   PetscFunctionBegin;
16389566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw));
16399566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(draw,&isnull));
1640abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1641f1af5d2fSBarry Smith 
1642d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1643f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
16449566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw,xl,yl,xr,yr));
16459566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer));
16469566063dSJacob Faibussowitsch   PetscCall(PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A));
16479566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL));
16489566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
1649f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1650f1af5d2fSBarry Smith }
1651f1af5d2fSBarry Smith 
1652dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1653932b0c3eSLois Curfman McInnes {
1654ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1655932b0c3eSLois Curfman McInnes 
16563a40ed3dSBarry Smith   PetscFunctionBegin;
16579566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
16589566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
16599566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw));
1660c45a1595SBarry Smith   if (iascii) {
16619566063dSJacob Faibussowitsch     PetscCall(MatView_SeqDense_ASCII(A,viewer));
16620f5bd95cSBarry Smith   } else if (isbinary) {
16639566063dSJacob Faibussowitsch     PetscCall(MatView_Dense_Binary(A,viewer));
1664f1af5d2fSBarry Smith   } else if (isdraw) {
16659566063dSJacob Faibussowitsch     PetscCall(MatView_SeqDense_Draw(A,viewer));
1666932b0c3eSLois Curfman McInnes   }
16673a40ed3dSBarry Smith   PetscFunctionReturn(0);
1668932b0c3eSLois Curfman McInnes }
1669289bc588SBarry Smith 
1670637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array)
1671d3042a70SBarry Smith {
1672d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1673d3042a70SBarry Smith 
1674d3042a70SBarry Smith   PetscFunctionBegin;
167528b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
167628b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
167728b400f6SJacob Faibussowitsch   PetscCheck(!a->unplacedarray,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreArray() first");
1678d3042a70SBarry Smith   a->unplacedarray       = a->v;
1679d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1680d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1681637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1682ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1683c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1684ca15aa20SStefano Zampini #endif
1685d3042a70SBarry Smith   PetscFunctionReturn(0);
1686d3042a70SBarry Smith }
1687d3042a70SBarry Smith 
1688d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1689d3042a70SBarry Smith {
1690d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1691d3042a70SBarry Smith 
1692d3042a70SBarry Smith   PetscFunctionBegin;
169328b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
169428b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1695d3042a70SBarry Smith   a->v             = a->unplacedarray;
1696d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1697d3042a70SBarry Smith   a->unplacedarray = NULL;
1698ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1699c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1700ca15aa20SStefano Zampini #endif
1701d3042a70SBarry Smith   PetscFunctionReturn(0);
1702d3042a70SBarry Smith }
1703d3042a70SBarry Smith 
1704d5ea218eSStefano Zampini static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A,const PetscScalar *array)
1705d5ea218eSStefano Zampini {
1706d5ea218eSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1707d5ea218eSStefano Zampini 
1708d5ea218eSStefano Zampini   PetscFunctionBegin;
170928b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
171028b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
17119566063dSJacob Faibussowitsch   if (!a->user_alloc) PetscCall(PetscFree(a->v));
1712d5ea218eSStefano Zampini   a->v           = (PetscScalar*) array;
1713d5ea218eSStefano Zampini   a->user_alloc  = PETSC_FALSE;
1714d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1715d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1716d5ea218eSStefano Zampini #endif
1717d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1718d5ea218eSStefano Zampini }
1719d5ea218eSStefano Zampini 
1720ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1721289bc588SBarry Smith {
1722ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
172390f02eecSBarry Smith 
17243a40ed3dSBarry Smith   PetscFunctionBegin;
1725aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1726c0aa6a63SJacob Faibussowitsch   PetscLogObjectState((PetscObject)mat,"Rows %" PetscInt_FMT " Cols %" PetscInt_FMT,mat->rmap->n,mat->cmap->n);
1727a5a9c739SBarry Smith #endif
17289566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(l->qrrhs)));
17299566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->tau));
17309566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->pivots));
17319566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->fwork));
17329566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->ptapwork));
17339566063dSJacob Faibussowitsch   if (!l->user_alloc) PetscCall(PetscFree(l->v));
17349566063dSJacob Faibussowitsch   if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray));
173528b400f6SJacob Faibussowitsch   PetscCheck(!l->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
173628b400f6SJacob Faibussowitsch   PetscCheck(!l->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
17379566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&l->cvec));
17389566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->cmat));
17399566063dSJacob Faibussowitsch   PetscCall(PetscFree(mat->data));
1740dbd8c25aSHong Zhang 
17419566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)mat,NULL));
17429566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatQRFactor_C",NULL));
1743*2e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatQRFactorSymbolic_C",NULL));
1744*2e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatQRFactorNumeric_C",NULL));
17459566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL));
17469566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseSetLDA_C",NULL));
17479566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL));
17489566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL));
17499566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL));
17509566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL));
17519566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseReplaceArray_C",NULL));
17529566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL));
17539566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL));
17549566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayWrite_C",NULL));
17559566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayWrite_C",NULL));
17569566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL));
17578baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17589566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL));
17598baccfbdSHong Zhang #endif
1760d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
17619566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_scalapack_C",NULL));
1762d24d4204SJose E. Roman #endif
17632bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17649566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL));
17659566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL));
17669566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL));
1767*2e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdensecuda_C",NULL));
17682bf066beSStefano Zampini #endif
17699566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL));
17709566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL));
17719566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL));
17729566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL));
17739566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL));
177452c5f739Sprj- 
17759566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL));
17769566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL));
17779566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVec_C",NULL));
17789566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVec_C",NULL));
17799566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecRead_C",NULL));
17809566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecRead_C",NULL));
17819566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecWrite_C",NULL));
17829566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecWrite_C",NULL));
17839566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetSubMatrix_C",NULL));
17849566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreSubMatrix_C",NULL));
17853a40ed3dSBarry Smith   PetscFunctionReturn(0);
1786289bc588SBarry Smith }
1787289bc588SBarry Smith 
1788e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1789289bc588SBarry Smith {
1790c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
17916536e3caSStefano Zampini   PetscInt       k,j,m = A->rmap->n, M = mat->lda, n = A->cmap->n;
179287828ca2SBarry Smith   PetscScalar    *v,tmp;
179348b35521SBarry Smith 
17943a40ed3dSBarry Smith   PetscFunctionBegin;
17956536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
17966536e3caSStefano Zampini     if (m == n) { /* in place transpose */
17979566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A,&v));
1798d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1799289bc588SBarry Smith         for (k=0; k<j; k++) {
18001b807ce4Svictorle           tmp        = v[j + k*M];
18011b807ce4Svictorle           v[j + k*M] = v[k + j*M];
18021b807ce4Svictorle           v[k + j*M] = tmp;
1803289bc588SBarry Smith         }
1804289bc588SBarry Smith       }
18059566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A,&v));
18066536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
18076536e3caSStefano Zampini       PetscScalar *v2;
18086536e3caSStefano Zampini       PetscLayout tmplayout;
18096536e3caSStefano Zampini 
18109566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1((size_t)m*n,&v2));
18119566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A,&v));
18126536e3caSStefano Zampini       for (j=0; j<n; j++) {
18136536e3caSStefano Zampini         for (k=0; k<m; k++) v2[j + (size_t)k*n] = v[k + (size_t)j*M];
18146536e3caSStefano Zampini       }
18159566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v,v2,(size_t)m*n));
18169566063dSJacob Faibussowitsch       PetscCall(PetscFree(v2));
18179566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A,&v));
18186536e3caSStefano Zampini       /* cleanup size dependent quantities */
18199566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&mat->cvec));
18209566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->cmat));
18219566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->pivots));
18229566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->fwork));
18239566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->ptapwork));
18246536e3caSStefano Zampini       /* swap row/col layouts */
18256536e3caSStefano Zampini       mat->lda  = n;
18266536e3caSStefano Zampini       tmplayout = A->rmap;
18276536e3caSStefano Zampini       A->rmap   = A->cmap;
18286536e3caSStefano Zampini       A->cmap   = tmplayout;
18296536e3caSStefano Zampini     }
18303a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1831d3e5ee88SLois Curfman McInnes     Mat          tmat;
1832ec8511deSBarry Smith     Mat_SeqDense *tmatd;
183387828ca2SBarry Smith     PetscScalar  *v2;
1834af36a384SStefano Zampini     PetscInt     M2;
1835ea709b57SSatish Balay 
18366536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
18379566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&tmat));
18389566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n));
18399566063dSJacob Faibussowitsch       PetscCall(MatSetType(tmat,((PetscObject)A)->type_name));
18409566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSetPreallocation(tmat,NULL));
1841ca15aa20SStefano Zampini     } else tmat = *matout;
1842ca15aa20SStefano Zampini 
18439566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&v));
18449566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(tmat,&v2));
1845ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1846ca15aa20SStefano Zampini     M2    = tmatd->lda;
1847d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1848af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1849d3e5ee88SLois Curfman McInnes     }
18509566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(tmat,&v2));
18519566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&v));
18529566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY));
18539566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY));
18546536e3caSStefano Zampini     *matout = tmat;
185548b35521SBarry Smith   }
18563a40ed3dSBarry Smith   PetscFunctionReturn(0);
1857289bc588SBarry Smith }
1858289bc588SBarry Smith 
1859e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1860289bc588SBarry Smith {
1861c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1862c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1863ca15aa20SStefano Zampini   PetscInt          i;
1864ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
18659ea5d5aeSSatish Balay 
18663a40ed3dSBarry Smith   PetscFunctionBegin;
1867d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1868d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
18699566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A1,&v1));
18709566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A2,&v2));
1871ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
18729566063dSJacob Faibussowitsch     PetscCall(PetscArraycmp(v1,v2,A1->rmap->n,flg));
1873ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1874ca15aa20SStefano Zampini     v1 += mat1->lda;
1875ca15aa20SStefano Zampini     v2 += mat2->lda;
18761b807ce4Svictorle   }
18779566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A1,&v1));
18789566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A2,&v2));
187977c4ece6SBarry Smith   *flg = PETSC_TRUE;
18803a40ed3dSBarry Smith   PetscFunctionReturn(0);
1881289bc588SBarry Smith }
1882289bc588SBarry Smith 
1883e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1884289bc588SBarry Smith {
1885c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
188613f74950SBarry Smith   PetscInt          i,n,len;
1887ca15aa20SStefano Zampini   PetscScalar       *x;
1888ca15aa20SStefano Zampini   const PetscScalar *vv;
188944cd7ae7SLois Curfman McInnes 
18903a40ed3dSBarry Smith   PetscFunctionBegin;
18919566063dSJacob Faibussowitsch   PetscCall(VecGetSize(v,&n));
18929566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
1893d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
18949566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&vv));
189508401ef6SPierre Jolivet   PetscCheck(n == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
189644cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1897ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1898289bc588SBarry Smith   }
18999566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&vv));
19009566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
19013a40ed3dSBarry Smith   PetscFunctionReturn(0);
1902289bc588SBarry Smith }
1903289bc588SBarry Smith 
1904e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1905289bc588SBarry Smith {
1906c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1907f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1908ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1909d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
191055659b69SBarry Smith 
19113a40ed3dSBarry Smith   PetscFunctionBegin;
19129566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&vv));
191328988994SBarry Smith   if (ll) {
19149566063dSJacob Faibussowitsch     PetscCall(VecGetSize(ll,&m));
19159566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ll,&l));
191608401ef6SPierre Jolivet     PetscCheck(m == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1917da3a660dSBarry Smith     for (i=0; i<m; i++) {
1918da3a660dSBarry Smith       x = l[i];
1919ca15aa20SStefano Zampini       v = vv + i;
1920b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1921da3a660dSBarry Smith     }
19229566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ll,&l));
19239566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*n*m));
1924da3a660dSBarry Smith   }
192528988994SBarry Smith   if (rr) {
19269566063dSJacob Faibussowitsch     PetscCall(VecGetSize(rr,&n));
19279566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(rr,&r));
192808401ef6SPierre Jolivet     PetscCheck(n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1929da3a660dSBarry Smith     for (i=0; i<n; i++) {
1930da3a660dSBarry Smith       x = r[i];
1931ca15aa20SStefano Zampini       v = vv + i*mat->lda;
19322205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1933da3a660dSBarry Smith     }
19349566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(rr,&r));
19359566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*n*m));
1936da3a660dSBarry Smith   }
19379566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&vv));
19383a40ed3dSBarry Smith   PetscFunctionReturn(0);
1939289bc588SBarry Smith }
1940289bc588SBarry Smith 
1941ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1942289bc588SBarry Smith {
1943c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1944ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1945329f5518SBarry Smith   PetscReal         sum = 0.0;
194675f6d85dSStefano Zampini   PetscInt          lda, m=A->rmap->n,i,j;
194755659b69SBarry Smith 
19483a40ed3dSBarry Smith   PetscFunctionBegin;
19499566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&vv));
19509566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(A,&lda));
1951ca15aa20SStefano Zampini   v    = vv;
1952289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1953a5ce6ee0Svictorle     if (lda>m) {
1954d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1955ca15aa20SStefano Zampini         v = vv+j*lda;
1956a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1957a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1958a5ce6ee0Svictorle         }
1959a5ce6ee0Svictorle       }
1960a5ce6ee0Svictorle     } else {
1961570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1962570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
196373cf7048SBarry Smith       PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&cnt,v,&one));
1964570b7f6dSBarry Smith     }
1965570b7f6dSBarry Smith #else
1966d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1967329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1968289bc588SBarry Smith       }
1969a5ce6ee0Svictorle     }
19708f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1971570b7f6dSBarry Smith #endif
19729566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0*A->cmap->n*A->rmap->n));
19733a40ed3dSBarry Smith   } else if (type == NORM_1) {
1974064f8208SBarry Smith     *nrm = 0.0;
1975d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1976ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
1977289bc588SBarry Smith       sum = 0.0;
1978d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
197933a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1980289bc588SBarry Smith       }
1981064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1982289bc588SBarry Smith     }
19839566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*A->cmap->n*A->rmap->n));
19843a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1985064f8208SBarry Smith     *nrm = 0.0;
1986d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1987ca15aa20SStefano Zampini       v   = vv + j;
1988289bc588SBarry Smith       sum = 0.0;
1989d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
19901b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1991289bc588SBarry Smith       }
1992064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1993289bc588SBarry Smith     }
19949566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*A->cmap->n*A->rmap->n));
1995e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
19969566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv));
19973a40ed3dSBarry Smith   PetscFunctionReturn(0);
1998289bc588SBarry Smith }
1999289bc588SBarry Smith 
2000e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
2001289bc588SBarry Smith {
2002c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
200367e560aaSBarry Smith 
20043a40ed3dSBarry Smith   PetscFunctionBegin;
2005b5a2b587SKris Buschelman   switch (op) {
2006b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
20074e0d8c25SBarry Smith     aij->roworiented = flg;
2008b5a2b587SKris Buschelman     break;
2009512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
2010b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
20113971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
20128c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
201313fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
2014b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
2015b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
20160f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
20175021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
2018071fcb05SBarry Smith   case MAT_SORTED_FULL:
20199566063dSJacob Faibussowitsch     PetscCall(PetscInfo(A,"Option %s ignored\n",MatOptions[op]));
20205021d80fSJed Brown     break;
20215021d80fSJed Brown   case MAT_SPD:
202277e54ba9SKris Buschelman   case MAT_SYMMETRIC:
202377e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
20249a4540c5SBarry Smith   case MAT_HERMITIAN:
20259a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
20265021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
202777e54ba9SKris Buschelman     break;
2028b5a2b587SKris Buschelman   default:
202998921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
20303a40ed3dSBarry Smith   }
20313a40ed3dSBarry Smith   PetscFunctionReturn(0);
2032289bc588SBarry Smith }
2033289bc588SBarry Smith 
20343d8925e7SStefano Zampini PetscErrorCode MatZeroEntries_SeqDense(Mat A)
20356f0a148fSBarry Smith {
2036ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
20373d8925e7SStefano Zampini   PetscInt       lda=l->lda,m=A->rmap->n,n=A->cmap->n,j;
2038ca15aa20SStefano Zampini   PetscScalar    *v;
20393a40ed3dSBarry Smith 
20403a40ed3dSBarry Smith   PetscFunctionBegin;
20419566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A,&v));
2042a5ce6ee0Svictorle   if (lda>m) {
20433d8925e7SStefano Zampini     for (j=0; j<n; j++) {
20449566063dSJacob Faibussowitsch       PetscCall(PetscArrayzero(v+j*lda,m));
2045a5ce6ee0Svictorle     }
2046a5ce6ee0Svictorle   } else {
20479566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(v,PetscInt64Mult(m,n)));
2048a5ce6ee0Svictorle   }
20499566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A,&v));
20503a40ed3dSBarry Smith   PetscFunctionReturn(0);
20516f0a148fSBarry Smith }
20526f0a148fSBarry Smith 
2053e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
20546f0a148fSBarry Smith {
2055ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
2056b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
2057ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
205897b48c8fSBarry Smith   const PetscScalar *xx;
205955659b69SBarry Smith 
20603a40ed3dSBarry Smith   PetscFunctionBegin;
206176bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2062b9679d65SBarry Smith     for (i=0; i<N; i++) {
206308401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
206408401ef6SPierre Jolivet       PetscCheck(rows[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %" PetscInt_FMT " requested to be zeroed greater than or equal number of rows %" PetscInt_FMT,rows[i],A->rmap->n);
2065b9679d65SBarry Smith     }
206676bd3646SJed Brown   }
2067ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
2068b9679d65SBarry Smith 
206997b48c8fSBarry Smith   /* fix right hand side if needed */
207097b48c8fSBarry Smith   if (x && b) {
20719566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x,&xx));
20729566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b,&bb));
20732205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
20749566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x,&xx));
20759566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b,&bb));
207697b48c8fSBarry Smith   }
207797b48c8fSBarry Smith 
20789566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
20796f0a148fSBarry Smith   for (i=0; i<N; i++) {
2080ca15aa20SStefano Zampini     slot = v + rows[i];
2081b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
20826f0a148fSBarry Smith   }
2083f4df32b1SMatthew Knepley   if (diag != 0.0) {
208408401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
20856f0a148fSBarry Smith     for (i=0; i<N; i++) {
2086ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
2087f4df32b1SMatthew Knepley       *slot = diag;
20886f0a148fSBarry Smith     }
20896f0a148fSBarry Smith   }
20909566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
20913a40ed3dSBarry Smith   PetscFunctionReturn(0);
20926f0a148fSBarry Smith }
2093557bce09SLois Curfman McInnes 
209449a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
209549a6ff4bSBarry Smith {
209649a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
209749a6ff4bSBarry Smith 
209849a6ff4bSBarry Smith   PetscFunctionBegin;
209949a6ff4bSBarry Smith   *lda = mat->lda;
210049a6ff4bSBarry Smith   PetscFunctionReturn(0);
210149a6ff4bSBarry Smith }
210249a6ff4bSBarry Smith 
2103637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array)
210464e87e97SBarry Smith {
2105c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
21063a40ed3dSBarry Smith 
21073a40ed3dSBarry Smith   PetscFunctionBegin;
210828b400f6SJacob Faibussowitsch   PetscCheck(!mat->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
210964e87e97SBarry Smith   *array = mat->v;
21103a40ed3dSBarry Smith   PetscFunctionReturn(0);
211164e87e97SBarry Smith }
21120754003eSLois Curfman McInnes 
2113637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array)
2114ff14e315SSatish Balay {
21153a40ed3dSBarry Smith   PetscFunctionBegin;
211675f6d85dSStefano Zampini   if (array) *array = NULL;
21173a40ed3dSBarry Smith   PetscFunctionReturn(0);
2118ff14e315SSatish Balay }
21190754003eSLois Curfman McInnes 
21200f74d2c1SSatish Balay /*@
212149a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
212249a6ff4bSBarry Smith 
2123ad16ce7aSStefano Zampini    Not collective
212449a6ff4bSBarry Smith 
212549a6ff4bSBarry Smith    Input Parameter:
212649a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
212749a6ff4bSBarry Smith 
212849a6ff4bSBarry Smith    Output Parameter:
212949a6ff4bSBarry Smith .   lda - the leading dimension
213049a6ff4bSBarry Smith 
213149a6ff4bSBarry Smith    Level: intermediate
213249a6ff4bSBarry Smith 
2133db781477SPatrick Sanan .seealso: `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()`
213449a6ff4bSBarry Smith @*/
213549a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
213649a6ff4bSBarry Smith {
213749a6ff4bSBarry Smith   PetscFunctionBegin;
2138d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2139dadcf809SJacob Faibussowitsch   PetscValidIntPointer(lda,2);
214075f6d85dSStefano Zampini   MatCheckPreallocated(A,1);
2141cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));
214249a6ff4bSBarry Smith   PetscFunctionReturn(0);
214349a6ff4bSBarry Smith }
214449a6ff4bSBarry Smith 
21450f74d2c1SSatish Balay /*@
2146ad16ce7aSStefano Zampini    MatDenseSetLDA - Sets the leading dimension of the array used by the dense matrix
2147ad16ce7aSStefano Zampini 
2148ad16ce7aSStefano Zampini    Not collective
2149ad16ce7aSStefano Zampini 
2150d8d19677SJose E. Roman    Input Parameters:
2151ad16ce7aSStefano Zampini +  mat - a MATSEQDENSE or MATMPIDENSE matrix
2152ad16ce7aSStefano Zampini -  lda - the leading dimension
2153ad16ce7aSStefano Zampini 
2154ad16ce7aSStefano Zampini    Level: intermediate
2155ad16ce7aSStefano Zampini 
2156db781477SPatrick Sanan .seealso: `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()`
2157ad16ce7aSStefano Zampini @*/
2158ad16ce7aSStefano Zampini PetscErrorCode  MatDenseSetLDA(Mat A,PetscInt lda)
2159ad16ce7aSStefano Zampini {
2160ad16ce7aSStefano Zampini   PetscFunctionBegin;
2161ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2162cac4c232SBarry Smith   PetscTryMethod(A,"MatDenseSetLDA_C",(Mat,PetscInt),(A,lda));
2163ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2164ad16ce7aSStefano Zampini }
2165ad16ce7aSStefano Zampini 
2166ad16ce7aSStefano Zampini /*@C
21676947451fSStefano Zampini    MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored
216873a71a0fSBarry Smith 
21698572280aSBarry Smith    Logically Collective on Mat
217073a71a0fSBarry Smith 
217173a71a0fSBarry Smith    Input Parameter:
21726947451fSStefano Zampini .  mat - a dense matrix
217373a71a0fSBarry Smith 
217473a71a0fSBarry Smith    Output Parameter:
217573a71a0fSBarry Smith .   array - pointer to the data
217673a71a0fSBarry Smith 
217773a71a0fSBarry Smith    Level: intermediate
217873a71a0fSBarry Smith 
2179db781477SPatrick Sanan .seealso: `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
218073a71a0fSBarry Smith @*/
21818c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
218273a71a0fSBarry Smith {
218373a71a0fSBarry Smith   PetscFunctionBegin;
2184d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2185d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2186cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));
218773a71a0fSBarry Smith   PetscFunctionReturn(0);
218873a71a0fSBarry Smith }
218973a71a0fSBarry Smith 
2190dec5eb66SMatthew G Knepley /*@C
2191579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
219273a71a0fSBarry Smith 
21938572280aSBarry Smith    Logically Collective on Mat
21948572280aSBarry Smith 
21958572280aSBarry Smith    Input Parameters:
21966947451fSStefano Zampini +  mat - a dense matrix
2197a2b725a8SWilliam Gropp -  array - pointer to the data
21988572280aSBarry Smith 
21998572280aSBarry Smith    Level: intermediate
22008572280aSBarry Smith 
2201db781477SPatrick Sanan .seealso: `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
22028572280aSBarry Smith @*/
22038572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
22048572280aSBarry Smith {
22058572280aSBarry Smith   PetscFunctionBegin;
2206d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2207d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2208cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));
22099566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
2210637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
2211637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2212637a0070SStefano Zampini #endif
22138572280aSBarry Smith   PetscFunctionReturn(0);
22148572280aSBarry Smith }
22158572280aSBarry Smith 
22168572280aSBarry Smith /*@C
22176947451fSStefano Zampini    MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored
22188572280aSBarry Smith 
22198572280aSBarry Smith    Not Collective
22208572280aSBarry Smith 
22218572280aSBarry Smith    Input Parameter:
22226947451fSStefano Zampini .  mat - a dense matrix
22238572280aSBarry Smith 
22248572280aSBarry Smith    Output Parameter:
22258572280aSBarry Smith .   array - pointer to the data
22268572280aSBarry Smith 
22278572280aSBarry Smith    Level: intermediate
22288572280aSBarry Smith 
2229db781477SPatrick Sanan .seealso: `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
22308572280aSBarry Smith @*/
22318572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
22328572280aSBarry Smith {
22338572280aSBarry Smith   PetscFunctionBegin;
2234d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2235d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2236cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));
22378572280aSBarry Smith   PetscFunctionReturn(0);
22388572280aSBarry Smith }
22398572280aSBarry Smith 
22408572280aSBarry Smith /*@C
22416947451fSStefano Zampini    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead()
22428572280aSBarry Smith 
224373a71a0fSBarry Smith    Not Collective
224473a71a0fSBarry Smith 
224573a71a0fSBarry Smith    Input Parameters:
22466947451fSStefano Zampini +  mat - a dense matrix
2247a2b725a8SWilliam Gropp -  array - pointer to the data
224873a71a0fSBarry Smith 
224973a71a0fSBarry Smith    Level: intermediate
225073a71a0fSBarry Smith 
2251db781477SPatrick Sanan .seealso: `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
225273a71a0fSBarry Smith @*/
22538572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
225473a71a0fSBarry Smith {
225573a71a0fSBarry Smith   PetscFunctionBegin;
2256d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2257d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2258cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));
225973a71a0fSBarry Smith   PetscFunctionReturn(0);
226073a71a0fSBarry Smith }
226173a71a0fSBarry Smith 
22626947451fSStefano Zampini /*@C
22636947451fSStefano Zampini    MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored
22646947451fSStefano Zampini 
22656947451fSStefano Zampini    Not Collective
22666947451fSStefano Zampini 
22676947451fSStefano Zampini    Input Parameter:
22686947451fSStefano Zampini .  mat - a dense matrix
22696947451fSStefano Zampini 
22706947451fSStefano Zampini    Output Parameter:
22716947451fSStefano Zampini .   array - pointer to the data
22726947451fSStefano Zampini 
22736947451fSStefano Zampini    Level: intermediate
22746947451fSStefano Zampini 
2275db781477SPatrick Sanan .seealso: `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22766947451fSStefano Zampini @*/
22776947451fSStefano Zampini PetscErrorCode  MatDenseGetArrayWrite(Mat A,PetscScalar **array)
22786947451fSStefano Zampini {
22796947451fSStefano Zampini   PetscFunctionBegin;
2280d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2281d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2282cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetArrayWrite_C",(Mat,PetscScalar**),(A,array));
22836947451fSStefano Zampini   PetscFunctionReturn(0);
22846947451fSStefano Zampini }
22856947451fSStefano Zampini 
22866947451fSStefano Zampini /*@C
22876947451fSStefano Zampini    MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite()
22886947451fSStefano Zampini 
22896947451fSStefano Zampini    Not Collective
22906947451fSStefano Zampini 
22916947451fSStefano Zampini    Input Parameters:
22926947451fSStefano Zampini +  mat - a dense matrix
22936947451fSStefano Zampini -  array - pointer to the data
22946947451fSStefano Zampini 
22956947451fSStefano Zampini    Level: intermediate
22966947451fSStefano Zampini 
2297db781477SPatrick Sanan .seealso: `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22986947451fSStefano Zampini @*/
22996947451fSStefano Zampini PetscErrorCode  MatDenseRestoreArrayWrite(Mat A,PetscScalar **array)
23006947451fSStefano Zampini {
23016947451fSStefano Zampini   PetscFunctionBegin;
2302d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2303d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2304cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreArrayWrite_C",(Mat,PetscScalar**),(A,array));
23059566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
23066947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
23076947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
23086947451fSStefano Zampini #endif
23096947451fSStefano Zampini   PetscFunctionReturn(0);
23106947451fSStefano Zampini }
23116947451fSStefano Zampini 
2312023c16fcSToby Isaac static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,MatReuse scall,Mat *B)
23130754003eSLois Curfman McInnes {
2314c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
2315bf5a80bcSToby Isaac   PetscInt       i,j,nrows,ncols,ldb;
23165d0c19d7SBarry Smith   const PetscInt *irow,*icol;
231787828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
23180754003eSLois Curfman McInnes   Mat            newmat;
23190754003eSLois Curfman McInnes 
23203a40ed3dSBarry Smith   PetscFunctionBegin;
23219566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isrow,&irow));
23229566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(iscol,&icol));
23239566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isrow,&nrows));
23249566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(iscol,&ncols));
23250754003eSLois Curfman McInnes 
2326182d2002SSatish Balay   /* Check submatrixcall */
2327182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
232813f74950SBarry Smith     PetscInt n_cols,n_rows;
23299566063dSJacob Faibussowitsch     PetscCall(MatGetSize(*B,&n_rows,&n_cols));
233021a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2331f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
23329566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(*B,nrows,ncols,nrows,ncols));
233321a2c019SBarry Smith     }
2334182d2002SSatish Balay     newmat = *B;
2335182d2002SSatish Balay   } else {
23360754003eSLois Curfman McInnes     /* Create and fill new matrix */
23379566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&newmat));
23389566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(newmat,nrows,ncols,nrows,ncols));
23399566063dSJacob Faibussowitsch     PetscCall(MatSetType(newmat,((PetscObject)A)->type_name));
23409566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(newmat,NULL));
2341182d2002SSatish Balay   }
2342182d2002SSatish Balay 
2343182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
23449566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(newmat,&bv));
23459566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(newmat,&ldb));
2346182d2002SSatish Balay   for (i=0; i<ncols; i++) {
23476de62eeeSBarry Smith     av = v + mat->lda*icol[i];
2348ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
2349bf5a80bcSToby Isaac     bv += ldb;
23500754003eSLois Curfman McInnes   }
23519566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(newmat,&bv));
2352182d2002SSatish Balay 
2353182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
23549566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY));
23559566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY));
23560754003eSLois Curfman McInnes 
23570754003eSLois Curfman McInnes   /* Free work space */
23589566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isrow,&irow));
23599566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(iscol,&icol));
2360182d2002SSatish Balay   *B   = newmat;
23613a40ed3dSBarry Smith   PetscFunctionReturn(0);
23620754003eSLois Curfman McInnes }
23630754003eSLois Curfman McInnes 
23647dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2365905e6a2fSBarry Smith {
236613f74950SBarry Smith   PetscInt       i;
2367905e6a2fSBarry Smith 
23683a40ed3dSBarry Smith   PetscFunctionBegin;
2369905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
23709566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(n,B));
2371905e6a2fSBarry Smith   }
2372905e6a2fSBarry Smith 
2373905e6a2fSBarry Smith   for (i=0; i<n; i++) {
23749566063dSJacob Faibussowitsch     PetscCall(MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],scall,&(*B)[i]));
2375905e6a2fSBarry Smith   }
23763a40ed3dSBarry Smith   PetscFunctionReturn(0);
2377905e6a2fSBarry Smith }
2378905e6a2fSBarry Smith 
2379e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2380c0aa2d19SHong Zhang {
2381c0aa2d19SHong Zhang   PetscFunctionBegin;
2382c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2383c0aa2d19SHong Zhang }
2384c0aa2d19SHong Zhang 
2385e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2386c0aa2d19SHong Zhang {
2387c0aa2d19SHong Zhang   PetscFunctionBegin;
2388c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2389c0aa2d19SHong Zhang }
2390c0aa2d19SHong Zhang 
2391a76f77c3SStefano Zampini PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
23924b0e389bSBarry Smith {
23934b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
2394ca15aa20SStefano Zampini   const PetscScalar *va;
2395ca15aa20SStefano Zampini   PetscScalar       *vb;
2396d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
23973a40ed3dSBarry Smith 
23983a40ed3dSBarry Smith   PetscFunctionBegin;
239933f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
240033f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
24019566063dSJacob Faibussowitsch     PetscCall(MatCopy_Basic(A,B,str));
24023a40ed3dSBarry Smith     PetscFunctionReturn(0);
24033a40ed3dSBarry Smith   }
2404aed4548fSBarry Smith   PetscCheck(m == B->rmap->n && n == B->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
24059566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&va));
24069566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(B,&vb));
2407a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
24080dbb7854Svictorle     for (j=0; j<n; j++) {
24099566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(vb+j*lda2,va+j*lda1,m));
2410a5ce6ee0Svictorle     }
2411a5ce6ee0Svictorle   } else {
24129566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vb,va,A->rmap->n*A->cmap->n));
2413a5ce6ee0Svictorle   }
24149566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(B,&vb));
24159566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&va));
24169566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
24179566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
2418273d9f13SBarry Smith   PetscFunctionReturn(0);
2419273d9f13SBarry Smith }
2420273d9f13SBarry Smith 
242175f6d85dSStefano Zampini PetscErrorCode MatSetUp_SeqDense(Mat A)
2422273d9f13SBarry Smith {
2423273d9f13SBarry Smith   PetscFunctionBegin;
24249566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->rmap));
24259566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->cmap));
242618992e5dSStefano Zampini   if (!A->preallocated) {
24279566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(A,NULL));
242818992e5dSStefano Zampini   }
24293a40ed3dSBarry Smith   PetscFunctionReturn(0);
24304b0e389bSBarry Smith }
24314b0e389bSBarry Smith 
2432ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2433ba337c44SJed Brown {
24344396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
243506c5243aSJose E. Roman   PetscInt       i,j;
24364396437dSToby Isaac   PetscInt       min = PetscMin(A->rmap->n,A->cmap->n);
2437ca15aa20SStefano Zampini   PetscScalar    *aa;
2438ba337c44SJed Brown 
2439ba337c44SJed Brown   PetscFunctionBegin;
24409566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&aa));
244106c5243aSJose E. Roman   for (j=0; j<A->cmap->n; j++) {
244206c5243aSJose E. Roman     for (i=0; i<A->rmap->n; i++) aa[i+j*mat->lda] = PetscConj(aa[i+j*mat->lda]);
244306c5243aSJose E. Roman   }
24449566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&aa));
24454396437dSToby Isaac   if (mat->tau) for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2446ba337c44SJed Brown   PetscFunctionReturn(0);
2447ba337c44SJed Brown }
2448ba337c44SJed Brown 
2449ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2450ba337c44SJed Brown {
245106c5243aSJose E. Roman   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
245206c5243aSJose E. Roman   PetscInt       i,j;
2453ca15aa20SStefano Zampini   PetscScalar    *aa;
2454ba337c44SJed Brown 
2455ba337c44SJed Brown   PetscFunctionBegin;
24569566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&aa));
245706c5243aSJose E. Roman   for (j=0; j<A->cmap->n; j++) {
245806c5243aSJose E. Roman     for (i=0; i<A->rmap->n; i++) aa[i+j*mat->lda] = PetscRealPart(aa[i+j*mat->lda]);
245906c5243aSJose E. Roman   }
24609566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&aa));
2461ba337c44SJed Brown   PetscFunctionReturn(0);
2462ba337c44SJed Brown }
2463ba337c44SJed Brown 
2464ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2465ba337c44SJed Brown {
246606c5243aSJose E. Roman   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
246706c5243aSJose E. Roman   PetscInt       i,j;
2468ca15aa20SStefano Zampini   PetscScalar    *aa;
2469ba337c44SJed Brown 
2470ba337c44SJed Brown   PetscFunctionBegin;
24719566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&aa));
247206c5243aSJose E. Roman   for (j=0; j<A->cmap->n; j++) {
247306c5243aSJose E. Roman     for (i=0; i<A->rmap->n; i++) aa[i+j*mat->lda] = PetscImaginaryPart(aa[i+j*mat->lda]);
247406c5243aSJose E. Roman   }
24759566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&aa));
2476ba337c44SJed Brown   PetscFunctionReturn(0);
2477ba337c44SJed Brown }
2478284134d9SBarry Smith 
2479a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
24804222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2481a9fe9ddaSSatish Balay {
2482d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
24837a3c3d58SStefano Zampini   PetscBool      cisdense;
2484a9fe9ddaSSatish Balay 
2485ee16a9a1SHong Zhang   PetscFunctionBegin;
24869566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,m,n,m,n));
24879566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
24887a3c3d58SStefano Zampini   if (!cisdense) {
24897a3c3d58SStefano Zampini     PetscBool flg;
24907a3c3d58SStefano Zampini 
24919566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg));
24929566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
24937a3c3d58SStefano Zampini   }
24949566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2495ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2496ee16a9a1SHong Zhang }
2497a9fe9ddaSSatish Balay 
2498a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2499a9fe9ddaSSatish Balay {
25006718818eSStefano Zampini   Mat_SeqDense       *a=(Mat_SeqDense*)A->data,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
25010805154bSBarry Smith   PetscBLASInt       m,n,k;
2502ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2503ca15aa20SStefano Zampini   PetscScalar       *cv;
2504a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2505a9fe9ddaSSatish Balay 
2506a9fe9ddaSSatish Balay   PetscFunctionBegin;
25079566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n,&m));
25089566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n,&n));
25099566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
251049d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25119566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&av));
25129566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,&bv));
25139566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C,&cv));
2514ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
25159566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1)));
25169566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&av));
25179566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,&bv));
25189566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C,&cv));
2519a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2520a9fe9ddaSSatish Balay }
2521a9fe9ddaSSatish Balay 
25224222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
252369f65d41SStefano Zampini {
252469f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
25257a3c3d58SStefano Zampini   PetscBool      cisdense;
252669f65d41SStefano Zampini 
252769f65d41SStefano Zampini   PetscFunctionBegin;
25289566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,m,n,m,n));
25299566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
25307a3c3d58SStefano Zampini   if (!cisdense) {
25317a3c3d58SStefano Zampini     PetscBool flg;
25327a3c3d58SStefano Zampini 
25339566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg));
25349566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
25357a3c3d58SStefano Zampini   }
25369566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
253769f65d41SStefano Zampini   PetscFunctionReturn(0);
253869f65d41SStefano Zampini }
253969f65d41SStefano Zampini 
254069f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
254169f65d41SStefano Zampini {
254269f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
254369f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
254469f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
25456718818eSStefano Zampini   const PetscScalar *av,*bv;
25466718818eSStefano Zampini   PetscScalar       *cv;
254769f65d41SStefano Zampini   PetscBLASInt      m,n,k;
254869f65d41SStefano Zampini   PetscScalar       _DOne=1.0,_DZero=0.0;
254969f65d41SStefano Zampini 
255069f65d41SStefano Zampini   PetscFunctionBegin;
25519566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n,&m));
25529566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n,&n));
25539566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
255449d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25559566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&av));
25569566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,&bv));
25579566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C,&cv));
25586718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
25599566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&av));
25609566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,&bv));
25619566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C,&cv));
25629566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1)));
256369f65d41SStefano Zampini   PetscFunctionReturn(0);
256469f65d41SStefano Zampini }
256569f65d41SStefano Zampini 
25664222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2567a9fe9ddaSSatish Balay {
2568d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
25697a3c3d58SStefano Zampini   PetscBool      cisdense;
2570a9fe9ddaSSatish Balay 
2571ee16a9a1SHong Zhang   PetscFunctionBegin;
25729566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,m,n,m,n));
25739566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
25747a3c3d58SStefano Zampini   if (!cisdense) {
25757a3c3d58SStefano Zampini     PetscBool flg;
25767a3c3d58SStefano Zampini 
25779566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg));
25789566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
25797a3c3d58SStefano Zampini   }
25809566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2581ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2582ee16a9a1SHong Zhang }
2583a9fe9ddaSSatish Balay 
258475648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2585a9fe9ddaSSatish Balay {
2586a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2587a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
2588a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
25896718818eSStefano Zampini   const PetscScalar *av,*bv;
25906718818eSStefano Zampini   PetscScalar       *cv;
25910805154bSBarry Smith   PetscBLASInt      m,n,k;
2592a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2593a9fe9ddaSSatish Balay 
2594a9fe9ddaSSatish Balay   PetscFunctionBegin;
25959566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n,&m));
25969566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n,&n));
25979566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&k));
259849d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25999566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&av));
26009566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,&bv));
26019566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C,&cv));
26026718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
26039566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&av));
26049566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,&bv));
26059566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C,&cv));
26069566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1)));
2607a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2608a9fe9ddaSSatish Balay }
2609985db425SBarry Smith 
26104222ddf1SHong Zhang /* ----------------------------------------------- */
26114222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
26124222ddf1SHong Zhang {
26134222ddf1SHong Zhang   PetscFunctionBegin;
26144222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
26154222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
26164222ddf1SHong Zhang   PetscFunctionReturn(0);
26174222ddf1SHong Zhang }
26184222ddf1SHong Zhang 
26194222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
26204222ddf1SHong Zhang {
26214222ddf1SHong Zhang   PetscFunctionBegin;
26224222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
26234222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
26244222ddf1SHong Zhang   PetscFunctionReturn(0);
26254222ddf1SHong Zhang }
26264222ddf1SHong Zhang 
26274222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
26284222ddf1SHong Zhang {
26294222ddf1SHong Zhang   PetscFunctionBegin;
26304222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
26314222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
26324222ddf1SHong Zhang   PetscFunctionReturn(0);
26334222ddf1SHong Zhang }
26344222ddf1SHong Zhang 
26354222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
26364222ddf1SHong Zhang {
26374222ddf1SHong Zhang   Mat_Product    *product = C->product;
26384222ddf1SHong Zhang 
26394222ddf1SHong Zhang   PetscFunctionBegin;
26404222ddf1SHong Zhang   switch (product->type) {
26414222ddf1SHong Zhang   case MATPRODUCT_AB:
26429566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AB(C));
26434222ddf1SHong Zhang     break;
26444222ddf1SHong Zhang   case MATPRODUCT_AtB:
26459566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AtB(C));
26464222ddf1SHong Zhang     break;
26474222ddf1SHong Zhang   case MATPRODUCT_ABt:
26489566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_ABt(C));
26494222ddf1SHong Zhang     break;
26506718818eSStefano Zampini   default:
26514222ddf1SHong Zhang     break;
26524222ddf1SHong Zhang   }
26534222ddf1SHong Zhang   PetscFunctionReturn(0);
26544222ddf1SHong Zhang }
26554222ddf1SHong Zhang /* ----------------------------------------------- */
26564222ddf1SHong Zhang 
2657e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2658985db425SBarry Smith {
2659985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2660d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2661985db425SBarry Smith   PetscScalar        *x;
2662ca15aa20SStefano Zampini   const PetscScalar *aa;
2663985db425SBarry Smith 
2664985db425SBarry Smith   PetscFunctionBegin;
266528b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
26669566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
26679566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v,&p));
26689566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
266908401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2670985db425SBarry Smith   for (i=0; i<m; i++) {
2671985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2672985db425SBarry Smith     for (j=1; j<n; j++) {
2673ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2674985db425SBarry Smith     }
2675985db425SBarry Smith   }
26769566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
26779566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
2678985db425SBarry Smith   PetscFunctionReturn(0);
2679985db425SBarry Smith }
2680985db425SBarry Smith 
2681e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2682985db425SBarry Smith {
2683985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2684d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2685985db425SBarry Smith   PetscScalar       *x;
2686985db425SBarry Smith   PetscReal         atmp;
2687ca15aa20SStefano Zampini   const PetscScalar *aa;
2688985db425SBarry Smith 
2689985db425SBarry Smith   PetscFunctionBegin;
269028b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
26919566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
26929566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v,&p));
26939566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
269408401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2695985db425SBarry Smith   for (i=0; i<m; i++) {
26969189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2697985db425SBarry Smith     for (j=1; j<n; j++) {
2698ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2699985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2700985db425SBarry Smith     }
2701985db425SBarry Smith   }
27029566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
27039566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
2704985db425SBarry Smith   PetscFunctionReturn(0);
2705985db425SBarry Smith }
2706985db425SBarry Smith 
2707e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2708985db425SBarry Smith {
2709985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2710d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2711985db425SBarry Smith   PetscScalar       *x;
2712ca15aa20SStefano Zampini   const PetscScalar *aa;
2713985db425SBarry Smith 
2714985db425SBarry Smith   PetscFunctionBegin;
271528b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
27169566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
27179566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
27189566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v,&p));
271908401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2720985db425SBarry Smith   for (i=0; i<m; i++) {
2721985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2722985db425SBarry Smith     for (j=1; j<n; j++) {
2723ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2724985db425SBarry Smith     }
2725985db425SBarry Smith   }
27269566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
27279566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
2728985db425SBarry Smith   PetscFunctionReturn(0);
2729985db425SBarry Smith }
2730985db425SBarry Smith 
2731637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
27328d0534beSBarry Smith {
27338d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
27348d0534beSBarry Smith   PetscScalar       *x;
2735ca15aa20SStefano Zampini   const PetscScalar *aa;
27368d0534beSBarry Smith 
27378d0534beSBarry Smith   PetscFunctionBegin;
273828b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
27399566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
27409566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
27419566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(x,aa+col*a->lda,A->rmap->n));
27429566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
27439566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
27448d0534beSBarry Smith   PetscFunctionReturn(0);
27458d0534beSBarry Smith }
27468d0534beSBarry Smith 
2747857cbf51SRichard Tran Mills PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A,PetscInt type,PetscReal *reductions)
27480716a85fSBarry Smith {
27490716a85fSBarry Smith   PetscInt          i,j,m,n;
27501683a169SBarry Smith   const PetscScalar *a;
27510716a85fSBarry Smith 
27520716a85fSBarry Smith   PetscFunctionBegin;
27539566063dSJacob Faibussowitsch   PetscCall(MatGetSize(A,&m,&n));
27549566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(reductions,n));
27559566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&a));
2756857cbf51SRichard Tran Mills   if (type == NORM_2) {
27570716a85fSBarry Smith     for (i=0; i<n; i++) {
27580716a85fSBarry Smith       for (j=0; j<m; j++) {
2759a873a8cdSSam Reynolds         reductions[i] += PetscAbsScalar(a[j]*a[j]);
27600716a85fSBarry Smith       }
27610716a85fSBarry Smith       a += m;
27620716a85fSBarry Smith     }
2763857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
27640716a85fSBarry Smith     for (i=0; i<n; i++) {
27650716a85fSBarry Smith       for (j=0; j<m; j++) {
2766a873a8cdSSam Reynolds         reductions[i] += PetscAbsScalar(a[j]);
27670716a85fSBarry Smith       }
27680716a85fSBarry Smith       a += m;
27690716a85fSBarry Smith     }
2770857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
27710716a85fSBarry Smith     for (i=0; i<n; i++) {
27720716a85fSBarry Smith       for (j=0; j<m; j++) {
2773a873a8cdSSam Reynolds         reductions[i] = PetscMax(PetscAbsScalar(a[j]),reductions[i]);
27740716a85fSBarry Smith       }
27750716a85fSBarry Smith       a += m;
27760716a85fSBarry Smith     }
2777857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
2778a873a8cdSSam Reynolds     for (i=0; i<n; i++) {
2779a873a8cdSSam Reynolds       for (j=0; j<m; j++) {
2780857cbf51SRichard Tran Mills         reductions[i] += PetscRealPart(a[j]);
2781a873a8cdSSam Reynolds       }
2782a873a8cdSSam Reynolds       a += m;
2783a873a8cdSSam Reynolds     }
2784857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2785857cbf51SRichard Tran Mills     for (i=0; i<n; i++) {
2786857cbf51SRichard Tran Mills       for (j=0; j<m; j++) {
2787857cbf51SRichard Tran Mills         reductions[i] += PetscImaginaryPart(a[j]);
2788857cbf51SRichard Tran Mills       }
2789857cbf51SRichard Tran Mills       a += m;
2790857cbf51SRichard Tran Mills     }
2791857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown reduction type");
27929566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&a));
2793857cbf51SRichard Tran Mills   if (type == NORM_2) {
2794a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
2795857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2796a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] /= m;
27970716a85fSBarry Smith   }
27980716a85fSBarry Smith   PetscFunctionReturn(0);
27990716a85fSBarry Smith }
28000716a85fSBarry Smith 
280173a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
280273a71a0fSBarry Smith {
280373a71a0fSBarry Smith   PetscScalar    *a;
2804637a0070SStefano Zampini   PetscInt       lda,m,n,i,j;
280573a71a0fSBarry Smith 
280673a71a0fSBarry Smith   PetscFunctionBegin;
28079566063dSJacob Faibussowitsch   PetscCall(MatGetSize(x,&m,&n));
28089566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(x,&lda));
28099566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(x,&a));
2810637a0070SStefano Zampini   for (j=0; j<n; j++) {
2811637a0070SStefano Zampini     for (i=0; i<m; i++) {
28129566063dSJacob Faibussowitsch       PetscCall(PetscRandomGetValue(rctx,a+j*lda+i));
2813637a0070SStefano Zampini     }
281473a71a0fSBarry Smith   }
28159566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(x,&a));
281673a71a0fSBarry Smith   PetscFunctionReturn(0);
281773a71a0fSBarry Smith }
281873a71a0fSBarry Smith 
28193b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
28203b49f96aSBarry Smith {
28213b49f96aSBarry Smith   PetscFunctionBegin;
28223b49f96aSBarry Smith   *missing = PETSC_FALSE;
28233b49f96aSBarry Smith   PetscFunctionReturn(0);
28243b49f96aSBarry Smith }
282573a71a0fSBarry Smith 
2826ca15aa20SStefano Zampini /* vals is not const */
2827af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
282886aefd0dSHong Zhang {
282986aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2830ca15aa20SStefano Zampini   PetscScalar    *v;
283186aefd0dSHong Zhang 
283286aefd0dSHong Zhang   PetscFunctionBegin;
283328b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
28349566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
2835ca15aa20SStefano Zampini   *vals = v+col*a->lda;
28369566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
283786aefd0dSHong Zhang   PetscFunctionReturn(0);
283886aefd0dSHong Zhang }
283986aefd0dSHong Zhang 
2840af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
284186aefd0dSHong Zhang {
284286aefd0dSHong Zhang   PetscFunctionBegin;
2843a5b23f4aSJose E. Roman   *vals = NULL; /* user cannot accidentally use the array later */
284486aefd0dSHong Zhang   PetscFunctionReturn(0);
284586aefd0dSHong Zhang }
2846abc3b08eSStefano Zampini 
2847289bc588SBarry Smith /* -------------------------------------------------------------------*/
2848a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2849905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2850905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2851905e6a2fSBarry Smith                                         MatMult_SeqDense,
285297304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
28537c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
28547c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2855f4259b30SLisandro Dalcin                                         NULL,
2856f4259b30SLisandro Dalcin                                         NULL,
2857f4259b30SLisandro Dalcin                                         NULL,
2858f4259b30SLisandro Dalcin                                 /* 10*/ NULL,
2859905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2860905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
286141f059aeSBarry Smith                                         MatSOR_SeqDense,
2862ec8511deSBarry Smith                                         MatTranspose_SeqDense,
286397304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2864905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2865905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2866905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2867905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2868c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2869c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2870905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2871905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2872d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2873f4259b30SLisandro Dalcin                                         NULL,
2874f4259b30SLisandro Dalcin                                         NULL,
2875f4259b30SLisandro Dalcin                                         NULL,
2876f4259b30SLisandro Dalcin                                         NULL,
28774994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2878f4259b30SLisandro Dalcin                                         NULL,
2879f4259b30SLisandro Dalcin                                         NULL,
2880f4259b30SLisandro Dalcin                                         NULL,
2881f4259b30SLisandro Dalcin                                         NULL,
2882d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2883f4259b30SLisandro Dalcin                                         NULL,
2884f4259b30SLisandro Dalcin                                         NULL,
2885f4259b30SLisandro Dalcin                                         NULL,
2886f4259b30SLisandro Dalcin                                         NULL,
2887d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
28887dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2889f4259b30SLisandro Dalcin                                         NULL,
28904b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2891a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2892d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2893a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
28942f605a99SJose E. Roman                                         MatShift_SeqDense,
2895f4259b30SLisandro Dalcin                                         NULL,
28963f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
289773a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2898f4259b30SLisandro Dalcin                                         NULL,
2899f4259b30SLisandro Dalcin                                         NULL,
2900f4259b30SLisandro Dalcin                                         NULL,
2901f4259b30SLisandro Dalcin                                         NULL,
2902f4259b30SLisandro Dalcin                                 /* 54*/ NULL,
2903f4259b30SLisandro Dalcin                                         NULL,
2904f4259b30SLisandro Dalcin                                         NULL,
2905f4259b30SLisandro Dalcin                                         NULL,
2906f4259b30SLisandro Dalcin                                         NULL,
2907023c16fcSToby Isaac                                 /* 59*/ MatCreateSubMatrix_SeqDense,
2908e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2909e03a110bSBarry Smith                                         MatView_SeqDense,
2910f4259b30SLisandro Dalcin                                         NULL,
2911f4259b30SLisandro Dalcin                                         NULL,
2912f4259b30SLisandro Dalcin                                 /* 64*/ NULL,
2913f4259b30SLisandro Dalcin                                         NULL,
2914f4259b30SLisandro Dalcin                                         NULL,
2915f4259b30SLisandro Dalcin                                         NULL,
2916f4259b30SLisandro Dalcin                                         NULL,
2917d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
2918f4259b30SLisandro Dalcin                                         NULL,
2919f4259b30SLisandro Dalcin                                         NULL,
2920f4259b30SLisandro Dalcin                                         NULL,
2921f4259b30SLisandro Dalcin                                         NULL,
2922f4259b30SLisandro Dalcin                                 /* 74*/ NULL,
2923f4259b30SLisandro Dalcin                                         NULL,
2924f4259b30SLisandro Dalcin                                         NULL,
2925f4259b30SLisandro Dalcin                                         NULL,
2926f4259b30SLisandro Dalcin                                         NULL,
2927f4259b30SLisandro Dalcin                                 /* 79*/ NULL,
2928f4259b30SLisandro Dalcin                                         NULL,
2929f4259b30SLisandro Dalcin                                         NULL,
2930f4259b30SLisandro Dalcin                                         NULL,
29315bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2932637a0070SStefano Zampini                                         MatIsSymmetric_SeqDense,
29331cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2934f4259b30SLisandro Dalcin                                         NULL,
2935f4259b30SLisandro Dalcin                                         NULL,
2936f4259b30SLisandro Dalcin                                         NULL,
2937f4259b30SLisandro Dalcin                                 /* 89*/ NULL,
2938f4259b30SLisandro Dalcin                                         NULL,
2939a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2940f4259b30SLisandro Dalcin                                         NULL,
2941f4259b30SLisandro Dalcin                                         NULL,
2942f4259b30SLisandro Dalcin                                 /* 94*/ NULL,
2943f4259b30SLisandro Dalcin                                         NULL,
2944f4259b30SLisandro Dalcin                                         NULL,
294569f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2946f4259b30SLisandro Dalcin                                         NULL,
29474222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
2948f4259b30SLisandro Dalcin                                         NULL,
2949f4259b30SLisandro Dalcin                                         NULL,
2950ba337c44SJed Brown                                         MatConjugate_SeqDense,
2951f4259b30SLisandro Dalcin                                         NULL,
2952f4259b30SLisandro Dalcin                                 /*104*/ NULL,
2953ba337c44SJed Brown                                         MatRealPart_SeqDense,
2954ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2955f4259b30SLisandro Dalcin                                         NULL,
2956f4259b30SLisandro Dalcin                                         NULL,
2957f4259b30SLisandro Dalcin                                 /*109*/ NULL,
2958f4259b30SLisandro Dalcin                                         NULL,
29598d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2960aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
29613b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2962f4259b30SLisandro Dalcin                                 /*114*/ NULL,
2963f4259b30SLisandro Dalcin                                         NULL,
2964f4259b30SLisandro Dalcin                                         NULL,
2965f4259b30SLisandro Dalcin                                         NULL,
2966f4259b30SLisandro Dalcin                                         NULL,
2967f4259b30SLisandro Dalcin                                 /*119*/ NULL,
2968f4259b30SLisandro Dalcin                                         NULL,
2969f4259b30SLisandro Dalcin                                         NULL,
2970f4259b30SLisandro Dalcin                                         NULL,
2971f4259b30SLisandro Dalcin                                         NULL,
2972f4259b30SLisandro Dalcin                                 /*124*/ NULL,
2973a873a8cdSSam Reynolds                                         MatGetColumnReductions_SeqDense,
2974f4259b30SLisandro Dalcin                                         NULL,
2975f4259b30SLisandro Dalcin                                         NULL,
2976f4259b30SLisandro Dalcin                                         NULL,
2977f4259b30SLisandro Dalcin                                 /*129*/ NULL,
2978f4259b30SLisandro Dalcin                                         NULL,
2979f4259b30SLisandro Dalcin                                         NULL,
298075648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
2981f4259b30SLisandro Dalcin                                         NULL,
2982f4259b30SLisandro Dalcin                                 /*134*/ NULL,
2983f4259b30SLisandro Dalcin                                         NULL,
2984f4259b30SLisandro Dalcin                                         NULL,
2985f4259b30SLisandro Dalcin                                         NULL,
2986f4259b30SLisandro Dalcin                                         NULL,
2987f4259b30SLisandro Dalcin                                 /*139*/ NULL,
2988f4259b30SLisandro Dalcin                                         NULL,
2989f4259b30SLisandro Dalcin                                         NULL,
2990f4259b30SLisandro Dalcin                                         NULL,
2991f4259b30SLisandro Dalcin                                         NULL,
29924222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
2993f4259b30SLisandro Dalcin                                 /*145*/ NULL,
2994f4259b30SLisandro Dalcin                                         NULL,
2995f4259b30SLisandro Dalcin                                         NULL
2996985db425SBarry Smith };
299790ace30eSBarry Smith 
29984b828684SBarry Smith /*@C
2999fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
3000d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
3001d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
3002289bc588SBarry Smith 
3003d083f849SBarry Smith    Collective
3004db81eaa0SLois Curfman McInnes 
300520563c6bSBarry Smith    Input Parameters:
3006db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
30070c775827SLois Curfman McInnes .  m - number of rows
300818f449edSLois Curfman McInnes .  n - number of columns
30090298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
3010dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
301120563c6bSBarry Smith 
301220563c6bSBarry Smith    Output Parameter:
301344cd7ae7SLois Curfman McInnes .  A - the matrix
301420563c6bSBarry Smith 
3015b259b22eSLois Curfman McInnes    Notes:
301618f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
301718f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
30180298fd71SBarry Smith    set data=NULL.
301918f449edSLois Curfman McInnes 
3020027ccd11SLois Curfman McInnes    Level: intermediate
3021027ccd11SLois Curfman McInnes 
3022db781477SPatrick Sanan .seealso: `MatCreate()`, `MatCreateDense()`, `MatSetValues()`
302320563c6bSBarry Smith @*/
30247087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
3025289bc588SBarry Smith {
30263a40ed3dSBarry Smith   PetscFunctionBegin;
30279566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm,A));
30289566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A,m,n,m,n));
30299566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A,MATSEQDENSE));
30309566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(*A,data));
3031273d9f13SBarry Smith   PetscFunctionReturn(0);
3032273d9f13SBarry Smith }
3033273d9f13SBarry Smith 
3034273d9f13SBarry Smith /*@C
3035273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
3036273d9f13SBarry Smith 
3037d083f849SBarry Smith    Collective
3038273d9f13SBarry Smith 
3039273d9f13SBarry Smith    Input Parameters:
30401c4f3114SJed Brown +  B - the matrix
30410298fd71SBarry Smith -  data - the array (or NULL)
3042273d9f13SBarry Smith 
3043273d9f13SBarry Smith    Notes:
3044273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
3045273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
3046284134d9SBarry Smith    need not call this routine.
3047273d9f13SBarry Smith 
3048273d9f13SBarry Smith    Level: intermediate
3049273d9f13SBarry Smith 
3050db781477SPatrick Sanan .seealso: `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()`
3051867c911aSBarry Smith 
3052273d9f13SBarry Smith @*/
30537087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
3054273d9f13SBarry Smith {
3055a23d5eceSKris Buschelman   PetscFunctionBegin;
3056d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
3057cac4c232SBarry Smith   PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));
3058a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3059a23d5eceSKris Buschelman }
3060a23d5eceSKris Buschelman 
30617087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
3062a23d5eceSKris Buschelman {
3063ad16ce7aSStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
3064273d9f13SBarry Smith 
3065273d9f13SBarry Smith   PetscFunctionBegin;
306628b400f6SJacob Faibussowitsch   PetscCheck(!b->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
3067273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3068a868139aSShri Abhyankar 
30699566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->rmap));
30709566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->cmap));
307134ef9618SShri Abhyankar 
3072ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
307386d161a7SShri Abhyankar 
30749e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
30759566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
30769566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1((size_t)b->lda*B->cmap->n,&b->v));
30779566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)B,b->lda*B->cmap->n*sizeof(PetscScalar)));
30782205254eSKarl Rupp 
30799e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
3080273d9f13SBarry Smith   } else { /* user-allocated storage */
30819566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
3082273d9f13SBarry Smith     b->v          = data;
3083273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
3084273d9f13SBarry Smith   }
30850450473dSBarry Smith   B->assembled = PETSC_TRUE;
3086273d9f13SBarry Smith   PetscFunctionReturn(0);
3087273d9f13SBarry Smith }
3088273d9f13SBarry Smith 
308965b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3090cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
30918baccfbdSHong Zhang {
3092d77f618aSHong Zhang   Mat               mat_elemental;
30931683a169SBarry Smith   const PetscScalar *array;
30941683a169SBarry Smith   PetscScalar       *v_colwise;
3095d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
3096d77f618aSHong Zhang 
30978baccfbdSHong Zhang   PetscFunctionBegin;
30989566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols));
30999566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&array));
3100d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3101d77f618aSHong Zhang   k = 0;
3102d77f618aSHong Zhang   for (j=0; j<N; j++) {
3103d77f618aSHong Zhang     cols[j] = j;
3104d77f618aSHong Zhang     for (i=0; i<M; i++) {
3105d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
3106d77f618aSHong Zhang     }
3107d77f618aSHong Zhang   }
3108d77f618aSHong Zhang   for (i=0; i<M; i++) {
3109d77f618aSHong Zhang     rows[i] = i;
3110d77f618aSHong Zhang   }
31119566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&array));
3112d77f618aSHong Zhang 
31139566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental));
31149566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N));
31159566063dSJacob Faibussowitsch   PetscCall(MatSetType(mat_elemental,MATELEMENTAL));
31169566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat_elemental));
3117d77f618aSHong Zhang 
3118d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
31199566063dSJacob Faibussowitsch   PetscCall(MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES));
31209566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY));
31219566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY));
31229566063dSJacob Faibussowitsch   PetscCall(PetscFree3(v_colwise,rows,cols));
3123d77f618aSHong Zhang 
3124511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
31259566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A,&mat_elemental));
3126d77f618aSHong Zhang   } else {
3127d77f618aSHong Zhang     *newmat = mat_elemental;
3128d77f618aSHong Zhang   }
31298baccfbdSHong Zhang   PetscFunctionReturn(0);
31308baccfbdSHong Zhang }
313165b80a83SHong Zhang #endif
31328baccfbdSHong Zhang 
313317359960SJose E. Roman PetscErrorCode  MatDenseSetLDA_SeqDense(Mat B,PetscInt lda)
31341b807ce4Svictorle {
31351b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
31367422da62SJose E. Roman   PetscBool    data;
313721a2c019SBarry Smith 
31381b807ce4Svictorle   PetscFunctionBegin;
31397422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
3140aed4548fSBarry Smith   PetscCheck(b->user_alloc || !data || b->lda == lda,PETSC_COMM_SELF,PETSC_ERR_ORDER,"LDA cannot be changed after allocation of internal storage");
314108401ef6SPierre Jolivet   PetscCheck(lda >= B->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"LDA %" PetscInt_FMT " must be at least matrix dimension %" PetscInt_FMT,lda,B->rmap->n);
31421b807ce4Svictorle   b->lda = lda;
31431b807ce4Svictorle   PetscFunctionReturn(0);
31441b807ce4Svictorle }
31451b807ce4Svictorle 
3146d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
3147d528f656SJakub Kruzik {
3148d528f656SJakub Kruzik   PetscMPIInt    size;
3149d528f656SJakub Kruzik 
3150d528f656SJakub Kruzik   PetscFunctionBegin;
31519566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm,&size));
3152d528f656SJakub Kruzik   if (size == 1) {
3153d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
31549566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(inmat,MAT_COPY_VALUES,outmat));
3155d528f656SJakub Kruzik     } else {
31569566063dSJacob Faibussowitsch       PetscCall(MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN));
3157d528f656SJakub Kruzik     }
3158d528f656SJakub Kruzik   } else {
31599566063dSJacob Faibussowitsch     PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat));
3160d528f656SJakub Kruzik   }
3161d528f656SJakub Kruzik   PetscFunctionReturn(0);
3162d528f656SJakub Kruzik }
3163d528f656SJakub Kruzik 
31646947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
31656947451fSStefano Zampini {
31666947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31676947451fSStefano Zampini 
31686947451fSStefano Zampini   PetscFunctionBegin;
316928b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
317028b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
31716947451fSStefano Zampini   if (!a->cvec) {
31729566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec));
31739566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec));
31746947451fSStefano Zampini   }
31756947451fSStefano Zampini   a->vecinuse = col + 1;
31769566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse));
31779566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda));
31786947451fSStefano Zampini   *v   = a->cvec;
31796947451fSStefano Zampini   PetscFunctionReturn(0);
31806947451fSStefano Zampini }
31816947451fSStefano Zampini 
31826947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
31836947451fSStefano Zampini {
31846947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31856947451fSStefano Zampini 
31866947451fSStefano Zampini   PetscFunctionBegin;
318728b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
318828b400f6SJacob Faibussowitsch   PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
31896947451fSStefano Zampini   a->vecinuse = 0;
31909566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse));
31919566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
319275f6d85dSStefano Zampini   if (v) *v = NULL;
31936947451fSStefano Zampini   PetscFunctionReturn(0);
31946947451fSStefano Zampini }
31956947451fSStefano Zampini 
31966947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
31976947451fSStefano Zampini {
31986947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31996947451fSStefano Zampini 
32006947451fSStefano Zampini   PetscFunctionBegin;
320128b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
320228b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32036947451fSStefano Zampini   if (!a->cvec) {
32049566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec));
32059566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec));
32066947451fSStefano Zampini   }
32076947451fSStefano Zampini   a->vecinuse = col + 1;
32089566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&a->ptrinuse));
32099566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda));
32109566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(a->cvec));
32116947451fSStefano Zampini   *v   = a->cvec;
32126947451fSStefano Zampini   PetscFunctionReturn(0);
32136947451fSStefano Zampini }
32146947451fSStefano Zampini 
32156947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
32166947451fSStefano Zampini {
32176947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32186947451fSStefano Zampini 
32196947451fSStefano Zampini   PetscFunctionBegin;
322028b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
322128b400f6SJacob Faibussowitsch   PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
32226947451fSStefano Zampini   a->vecinuse = 0;
32239566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&a->ptrinuse));
32249566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(a->cvec));
32259566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
322675f6d85dSStefano Zampini   if (v) *v = NULL;
32276947451fSStefano Zampini   PetscFunctionReturn(0);
32286947451fSStefano Zampini }
32296947451fSStefano Zampini 
32306947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
32316947451fSStefano Zampini {
32326947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32336947451fSStefano Zampini 
32346947451fSStefano Zampini   PetscFunctionBegin;
323528b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
323628b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32376947451fSStefano Zampini   if (!a->cvec) {
32389566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec));
32399566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec));
32406947451fSStefano Zampini   }
32416947451fSStefano Zampini   a->vecinuse = col + 1;
32429566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A,(PetscScalar**)&a->ptrinuse));
32439566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda));
32446947451fSStefano Zampini   *v   = a->cvec;
32456947451fSStefano Zampini   PetscFunctionReturn(0);
32466947451fSStefano Zampini }
32476947451fSStefano Zampini 
32486947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
32496947451fSStefano Zampini {
32506947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32516947451fSStefano Zampini 
32526947451fSStefano Zampini   PetscFunctionBegin;
325328b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
325428b400f6SJacob Faibussowitsch   PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
32556947451fSStefano Zampini   a->vecinuse = 0;
32569566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A,(PetscScalar**)&a->ptrinuse));
32579566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
325875f6d85dSStefano Zampini   if (v) *v = NULL;
32596947451fSStefano Zampini   PetscFunctionReturn(0);
32606947451fSStefano Zampini }
32616947451fSStefano Zampini 
3262a2748737SPierre Jolivet PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A,PetscInt rbegin,PetscInt rend,PetscInt cbegin,PetscInt cend,Mat *v)
32635ea7661aSPierre Jolivet {
32645ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32655ea7661aSPierre Jolivet 
32665ea7661aSPierre Jolivet   PetscFunctionBegin;
326728b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
326828b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
3269a2748737SPierre Jolivet   if (a->cmat && (cend-cbegin != a->cmat->cmap->N || rend-rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat));
32705ea7661aSPierre Jolivet   if (!a->cmat) {
3271a2748737SPierre Jolivet     PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A),rend-rbegin,PETSC_DECIDE,rend-rbegin,cend-cbegin,a->v+rbegin+(size_t)cbegin*a->lda,&a->cmat));
32729566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cmat));
32735ea7661aSPierre Jolivet   } else {
3274a2748737SPierre Jolivet     PetscCall(MatDensePlaceArray(a->cmat,a->v+rbegin+(size_t)cbegin*a->lda));
32755ea7661aSPierre Jolivet   }
32769566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(a->cmat,a->lda));
32775ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
32785ea7661aSPierre Jolivet   *v = a->cmat;
327975f6d85dSStefano Zampini #if defined(PETSC_HAVE_CUDA)
328075f6d85dSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
328175f6d85dSStefano Zampini #endif
32825ea7661aSPierre Jolivet   PetscFunctionReturn(0);
32835ea7661aSPierre Jolivet }
32845ea7661aSPierre Jolivet 
32855ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A,Mat *v)
32865ea7661aSPierre Jolivet {
32875ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32885ea7661aSPierre Jolivet 
32895ea7661aSPierre Jolivet   PetscFunctionBegin;
329028b400f6SJacob Faibussowitsch   PetscCheck(a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetSubMatrix() first");
329128b400f6SJacob Faibussowitsch   PetscCheck(a->cmat,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column matrix");
329208401ef6SPierre Jolivet   PetscCheck(*v == a->cmat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not the matrix obtained from MatDenseGetSubMatrix()");
32935ea7661aSPierre Jolivet   a->matinuse = 0;
32949566063dSJacob Faibussowitsch   PetscCall(MatDenseResetArray(a->cmat));
32955ea7661aSPierre Jolivet   *v   = NULL;
32965ea7661aSPierre Jolivet   PetscFunctionReturn(0);
32975ea7661aSPierre Jolivet }
32985ea7661aSPierre Jolivet 
32990bad9183SKris Buschelman /*MC
3300fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
33010bad9183SKris Buschelman 
33020bad9183SKris Buschelman    Options Database Keys:
33030bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
33040bad9183SKris Buschelman 
33050bad9183SKris Buschelman   Level: beginner
33060bad9183SKris Buschelman 
3307db781477SPatrick Sanan .seealso: `MatCreateSeqDense()`
330889665df3SBarry Smith 
33090bad9183SKris Buschelman M*/
3310ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
3311273d9f13SBarry Smith {
3312273d9f13SBarry Smith   Mat_SeqDense   *b;
33137c334f02SBarry Smith   PetscMPIInt    size;
3314273d9f13SBarry Smith 
3315273d9f13SBarry Smith   PetscFunctionBegin;
33169566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B),&size));
331708401ef6SPierre Jolivet   PetscCheck(size <= 1,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
331855659b69SBarry Smith 
33199566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(B,&b));
33209566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps)));
332144cd7ae7SLois Curfman McInnes   B->data = (void*)b;
332218f449edSLois Curfman McInnes 
3323273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
33244e220ebcSLois Curfman McInnes 
33259566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatQRFactor_C",MatQRFactor_SeqDense));
33269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense));
33279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseSetLDA_C",MatDenseSetLDA_SeqDense));
33289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense));
33299566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense));
33309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense));
33319566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense));
33329566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseReplaceArray_C",MatDenseReplaceArray_SeqDense));
33339566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense));
33349566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense));
33359566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayWrite_C",MatDenseGetArray_SeqDense));
33369566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayWrite_C",MatDenseRestoreArray_SeqDense));
33379566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ));
33388baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
33399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental));
33408baccfbdSHong Zhang #endif
3341d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
33429566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_scalapack_C",MatConvert_Dense_ScaLAPACK));
3343d24d4204SJose E. Roman #endif
33442bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
33459566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA));
33469566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense));
33479566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense));
33489566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense));
33492bf066beSStefano Zampini #endif
33509566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense));
33519566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense));
33529566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense));
33539566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense));
33549566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense));
335596e6d5c4SRichard Tran Mills 
33569566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense));
33579566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense));
33589566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVec_C",MatDenseGetColumnVec_SeqDense));
33599566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVec_C",MatDenseRestoreColumnVec_SeqDense));
33609566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecRead_C",MatDenseGetColumnVecRead_SeqDense));
33619566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecRead_C",MatDenseRestoreColumnVecRead_SeqDense));
33629566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecWrite_C",MatDenseGetColumnVecWrite_SeqDense));
33639566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecWrite_C",MatDenseRestoreColumnVecWrite_SeqDense));
33649566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetSubMatrix_C",MatDenseGetSubMatrix_SeqDense));
33659566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreSubMatrix_C",MatDenseRestoreSubMatrix_SeqDense));
33669566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE));
33673a40ed3dSBarry Smith   PetscFunctionReturn(0);
3368289bc588SBarry Smith }
336986aefd0dSHong Zhang 
337086aefd0dSHong Zhang /*@C
3371af53bab2SHong 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.
337286aefd0dSHong Zhang 
337386aefd0dSHong Zhang    Not Collective
337486aefd0dSHong Zhang 
33755ea7661aSPierre Jolivet    Input Parameters:
337686aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
337786aefd0dSHong Zhang -  col - column index
337886aefd0dSHong Zhang 
337986aefd0dSHong Zhang    Output Parameter:
338086aefd0dSHong Zhang .  vals - pointer to the data
338186aefd0dSHong Zhang 
338286aefd0dSHong Zhang    Level: intermediate
338386aefd0dSHong Zhang 
3384db781477SPatrick Sanan .seealso: `MatDenseRestoreColumn()`
338586aefd0dSHong Zhang @*/
338686aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
338786aefd0dSHong Zhang {
338886aefd0dSHong Zhang   PetscFunctionBegin;
3389d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3390d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3391d5ea218eSStefano Zampini   PetscValidPointer(vals,3);
3392cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));
339386aefd0dSHong Zhang   PetscFunctionReturn(0);
339486aefd0dSHong Zhang }
339586aefd0dSHong Zhang 
339686aefd0dSHong Zhang /*@C
339786aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
339886aefd0dSHong Zhang 
339986aefd0dSHong Zhang    Not Collective
340086aefd0dSHong Zhang 
340186aefd0dSHong Zhang    Input Parameter:
340286aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
340386aefd0dSHong Zhang 
340486aefd0dSHong Zhang    Output Parameter:
340586aefd0dSHong Zhang .  vals - pointer to the data
340686aefd0dSHong Zhang 
340786aefd0dSHong Zhang    Level: intermediate
340886aefd0dSHong Zhang 
3409db781477SPatrick Sanan .seealso: `MatDenseGetColumn()`
341086aefd0dSHong Zhang @*/
341186aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
341286aefd0dSHong Zhang {
341386aefd0dSHong Zhang   PetscFunctionBegin;
3414d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3415d5ea218eSStefano Zampini   PetscValidPointer(vals,2);
3416cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));
341786aefd0dSHong Zhang   PetscFunctionReturn(0);
341886aefd0dSHong Zhang }
34196947451fSStefano Zampini 
34200f74d2c1SSatish Balay /*@
34216947451fSStefano Zampini    MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec.
34226947451fSStefano Zampini 
34236947451fSStefano Zampini    Collective
34246947451fSStefano Zampini 
34255ea7661aSPierre Jolivet    Input Parameters:
34266947451fSStefano Zampini +  mat - the Mat object
34276947451fSStefano Zampini -  col - the column index
34286947451fSStefano Zampini 
34296947451fSStefano Zampini    Output Parameter:
34306947451fSStefano Zampini .  v - the vector
34316947451fSStefano Zampini 
34326947451fSStefano Zampini    Notes:
34336947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed.
34346947451fSStefano Zampini      Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access.
34356947451fSStefano Zampini 
34366947451fSStefano Zampini    Level: intermediate
34376947451fSStefano Zampini 
3438db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
34396947451fSStefano Zampini @*/
34406947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec(Mat A,PetscInt col,Vec *v)
34416947451fSStefano Zampini {
34426947451fSStefano Zampini   PetscFunctionBegin;
34436947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34446947451fSStefano Zampini   PetscValidType(A,1);
34456947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
34466947451fSStefano Zampini   PetscValidPointer(v,3);
344728b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
34482cf15c64SPierre Jolivet   PetscCheck(col >= 0 && col < A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
3449cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));
34506947451fSStefano Zampini   PetscFunctionReturn(0);
34516947451fSStefano Zampini }
34526947451fSStefano Zampini 
34530f74d2c1SSatish Balay /*@
34546947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
34556947451fSStefano Zampini 
34566947451fSStefano Zampini    Collective
34576947451fSStefano Zampini 
34585ea7661aSPierre Jolivet    Input Parameters:
34596947451fSStefano Zampini +  mat - the Mat object
34606947451fSStefano Zampini .  col - the column index
34616947451fSStefano Zampini -  v - the Vec object
34626947451fSStefano Zampini 
34636947451fSStefano Zampini    Level: intermediate
34646947451fSStefano Zampini 
3465db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
34666947451fSStefano Zampini @*/
34676947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec *v)
34686947451fSStefano Zampini {
34696947451fSStefano Zampini   PetscFunctionBegin;
34706947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34716947451fSStefano Zampini   PetscValidType(A,1);
34726947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
347308401ef6SPierre Jolivet   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
34742cf15c64SPierre Jolivet   PetscCheck(col >= 0 && col < A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
3475cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));
34766947451fSStefano Zampini   PetscFunctionReturn(0);
34776947451fSStefano Zampini }
34786947451fSStefano Zampini 
34790f74d2c1SSatish Balay /*@
34806947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
34816947451fSStefano Zampini 
34826947451fSStefano Zampini    Collective
34836947451fSStefano Zampini 
34845ea7661aSPierre Jolivet    Input Parameters:
34856947451fSStefano Zampini +  mat - the Mat object
34866947451fSStefano Zampini -  col - the column index
34876947451fSStefano Zampini 
34886947451fSStefano Zampini    Output Parameter:
34896947451fSStefano Zampini .  v - the vector
34906947451fSStefano Zampini 
34916947451fSStefano Zampini    Notes:
34926947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
34936947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
34946947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
34956947451fSStefano Zampini 
34966947451fSStefano Zampini    Level: intermediate
34976947451fSStefano Zampini 
3498db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
34996947451fSStefano Zampini @*/
35006947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec *v)
35016947451fSStefano Zampini {
35026947451fSStefano Zampini   PetscFunctionBegin;
35036947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35046947451fSStefano Zampini   PetscValidType(A,1);
35056947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35066947451fSStefano Zampini   PetscValidPointer(v,3);
350728b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35082cf15c64SPierre Jolivet   PetscCheck(col >= 0 && col < A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
3509cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));
35106947451fSStefano Zampini   PetscFunctionReturn(0);
35116947451fSStefano Zampini }
35126947451fSStefano Zampini 
35130f74d2c1SSatish Balay /*@
35146947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
35156947451fSStefano Zampini 
35166947451fSStefano Zampini    Collective
35176947451fSStefano Zampini 
35185ea7661aSPierre Jolivet    Input Parameters:
35196947451fSStefano Zampini +  mat - the Mat object
35206947451fSStefano Zampini .  col - the column index
35216947451fSStefano Zampini -  v - the Vec object
35226947451fSStefano Zampini 
35236947451fSStefano Zampini    Level: intermediate
35246947451fSStefano Zampini 
3525db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()`
35266947451fSStefano Zampini @*/
35276947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec *v)
35286947451fSStefano Zampini {
35296947451fSStefano Zampini   PetscFunctionBegin;
35306947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35316947451fSStefano Zampini   PetscValidType(A,1);
35326947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
353308401ef6SPierre Jolivet   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35342cf15c64SPierre Jolivet   PetscCheck(col >= 0 && col < A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
3535cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));
35366947451fSStefano Zampini   PetscFunctionReturn(0);
35376947451fSStefano Zampini }
35386947451fSStefano Zampini 
35390f74d2c1SSatish Balay /*@
35406947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
35416947451fSStefano Zampini 
35426947451fSStefano Zampini    Collective
35436947451fSStefano Zampini 
35445ea7661aSPierre Jolivet    Input Parameters:
35456947451fSStefano Zampini +  mat - the Mat object
35466947451fSStefano Zampini -  col - the column index
35476947451fSStefano Zampini 
35486947451fSStefano Zampini    Output Parameter:
35496947451fSStefano Zampini .  v - the vector
35506947451fSStefano Zampini 
35516947451fSStefano Zampini    Notes:
35526947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
35536947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
35546947451fSStefano Zampini 
35556947451fSStefano Zampini    Level: intermediate
35566947451fSStefano Zampini 
3557db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
35586947451fSStefano Zampini @*/
35596947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec *v)
35606947451fSStefano Zampini {
35616947451fSStefano Zampini   PetscFunctionBegin;
35626947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35636947451fSStefano Zampini   PetscValidType(A,1);
35646947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35656947451fSStefano Zampini   PetscValidPointer(v,3);
356628b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3567aed4548fSBarry Smith   PetscCheck(col >= 0 && col < A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
3568cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));
35696947451fSStefano Zampini   PetscFunctionReturn(0);
35706947451fSStefano Zampini }
35716947451fSStefano Zampini 
35720f74d2c1SSatish Balay /*@
35736947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
35746947451fSStefano Zampini 
35756947451fSStefano Zampini    Collective
35766947451fSStefano Zampini 
35775ea7661aSPierre Jolivet    Input Parameters:
35786947451fSStefano Zampini +  mat - the Mat object
35796947451fSStefano Zampini .  col - the column index
35806947451fSStefano Zampini -  v - the Vec object
35816947451fSStefano Zampini 
35826947451fSStefano Zampini    Level: intermediate
35836947451fSStefano Zampini 
3584db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`
35856947451fSStefano Zampini @*/
35866947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec *v)
35876947451fSStefano Zampini {
35886947451fSStefano Zampini   PetscFunctionBegin;
35896947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35906947451fSStefano Zampini   PetscValidType(A,1);
35916947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
359208401ef6SPierre Jolivet   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3593aed4548fSBarry Smith   PetscCheck(col >= 0 && col < A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
3594cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));
35956947451fSStefano Zampini   PetscFunctionReturn(0);
35966947451fSStefano Zampini }
35975ea7661aSPierre Jolivet 
35980f74d2c1SSatish Balay /*@
3599a2748737SPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat.
36005ea7661aSPierre Jolivet 
36015ea7661aSPierre Jolivet    Collective
36025ea7661aSPierre Jolivet 
36035ea7661aSPierre Jolivet    Input Parameters:
36045ea7661aSPierre Jolivet +  mat - the Mat object
3605a2748737SPierre Jolivet .  rbegin - the first global row index in the block (if PETSC_DECIDE, is 0)
3606a2748737SPierre Jolivet .  rend - the global row index past the last one in the block (if PETSC_DECIDE, is M)
3607a2748737SPierre Jolivet .  cbegin - the first global column index in the block (if PETSC_DECIDE, is 0)
3608a2748737SPierre Jolivet -  cend - the global column index past the last one in the block (if PETSC_DECIDE, is N)
36095ea7661aSPierre Jolivet 
36105ea7661aSPierre Jolivet    Output Parameter:
36115ea7661aSPierre Jolivet .  v - the matrix
36125ea7661aSPierre Jolivet 
36135ea7661aSPierre Jolivet    Notes:
36145ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
3615a2748737SPierre Jolivet      The output matrix is not redistributed by PETSc, so depending on the values of rbegin and rend, some processes may have no local rows.
36165ea7661aSPierre Jolivet 
36175ea7661aSPierre Jolivet    Level: intermediate
36185ea7661aSPierre Jolivet 
3619db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()`
36205ea7661aSPierre Jolivet @*/
3621a2748737SPierre Jolivet PetscErrorCode MatDenseGetSubMatrix(Mat A,PetscInt rbegin,PetscInt rend,PetscInt cbegin,PetscInt cend,Mat *v)
36225ea7661aSPierre Jolivet {
36235ea7661aSPierre Jolivet   PetscFunctionBegin;
36245ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36255ea7661aSPierre Jolivet   PetscValidType(A,1);
3626a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A,rbegin,2);
3627a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A,rend,3);
3628a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A,cbegin,4);
3629a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A,cend,5);
3630a2748737SPierre Jolivet   PetscValidPointer(v,6);
3631a2748737SPierre Jolivet   if (rbegin == PETSC_DECIDE) rbegin = 0;
3632a2748737SPierre Jolivet   if (rend == PETSC_DECIDE) rend = A->rmap->N;
3633a2748737SPierre Jolivet   if (cbegin == PETSC_DECIDE) cbegin = 0;
3634a2748737SPierre Jolivet   if (cend == PETSC_DECIDE) cend = A->cmap->N;
363528b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3636a2748737SPierre Jolivet   PetscCheck(rbegin >= 0 && rbegin <= A->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid rbegin %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT "]",rbegin,A->rmap->N);
3637a2748737SPierre Jolivet   PetscCheck(rend >= rbegin && rend <= A->rmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid rend %" PetscInt_FMT ", should be in [%" PetscInt_FMT ",%" PetscInt_FMT "]",rend,rbegin,A->rmap->N);
3638a2748737SPierre Jolivet   PetscCheck(cbegin >= 0 && cbegin <= A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid cbegin %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT "]",cbegin,A->cmap->N);
3639a2748737SPierre Jolivet   PetscCheck(cend >= cbegin && cend <= A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid cend %" PetscInt_FMT ", should be in [%" PetscInt_FMT ",%" PetscInt_FMT "]",cend,cbegin,A->cmap->N);
3640a2748737SPierre Jolivet   PetscUseMethod(A,"MatDenseGetSubMatrix_C",(Mat,PetscInt,PetscInt,PetscInt,PetscInt,Mat*),(A,rbegin,rend,cbegin,cend,v));
36415ea7661aSPierre Jolivet   PetscFunctionReturn(0);
36425ea7661aSPierre Jolivet }
36435ea7661aSPierre Jolivet 
36440f74d2c1SSatish Balay /*@
36455ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
36465ea7661aSPierre Jolivet 
36475ea7661aSPierre Jolivet    Collective
36485ea7661aSPierre Jolivet 
36495ea7661aSPierre Jolivet    Input Parameters:
36505ea7661aSPierre Jolivet +  mat - the Mat object
36515ea7661aSPierre Jolivet -  v - the Mat object
36525ea7661aSPierre Jolivet 
36535ea7661aSPierre Jolivet    Level: intermediate
36545ea7661aSPierre Jolivet 
3655db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()`
36565ea7661aSPierre Jolivet @*/
36575ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix(Mat A,Mat *v)
36585ea7661aSPierre Jolivet {
36595ea7661aSPierre Jolivet   PetscFunctionBegin;
36605ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36615ea7661aSPierre Jolivet   PetscValidType(A,1);
36625ea7661aSPierre Jolivet   PetscValidPointer(v,2);
3663cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreSubMatrix_C",(Mat,Mat*),(A,v));
36645ea7661aSPierre Jolivet   PetscFunctionReturn(0);
36655ea7661aSPierre Jolivet }
36668a9c020eSBarry Smith 
36678a9c020eSBarry Smith #include <petscblaslapack.h>
36688a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h>
36698a9c020eSBarry Smith 
36708a9c020eSBarry Smith PetscErrorCode MatSeqDenseInvert(Mat A)
36718a9c020eSBarry Smith {
36728a9c020eSBarry Smith   Mat_SeqDense    *a = (Mat_SeqDense*) A->data;
36738a9c020eSBarry Smith   PetscInt        bs = A->rmap->n;
36748a9c020eSBarry Smith   MatScalar       *values = a->v;
36758a9c020eSBarry Smith   const PetscReal shift = 0.0;
36768a9c020eSBarry Smith   PetscBool       allowzeropivot = PetscNot(A->erroriffailure),zeropivotdetected=PETSC_FALSE;
36778a9c020eSBarry Smith 
36788a9c020eSBarry Smith   PetscFunctionBegin;
36798a9c020eSBarry Smith   /* factor and invert each block */
36808a9c020eSBarry Smith   switch (bs) {
36818a9c020eSBarry Smith   case 1:
36828a9c020eSBarry Smith     values[0] = (PetscScalar)1.0 / (values[0] + shift);
36838a9c020eSBarry Smith     break;
36848a9c020eSBarry Smith   case 2:
36858a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_2(values,shift,allowzeropivot,&zeropivotdetected));
36868a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36878a9c020eSBarry Smith     break;
36888a9c020eSBarry Smith   case 3:
36898a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_3(values,shift,allowzeropivot,&zeropivotdetected));
36908a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36918a9c020eSBarry Smith     break;
36928a9c020eSBarry Smith   case 4:
36938a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_4(values,shift,allowzeropivot,&zeropivotdetected));
36948a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36958a9c020eSBarry Smith     break;
36968a9c020eSBarry Smith   case 5:
36978a9c020eSBarry Smith   {
36988a9c020eSBarry Smith     PetscScalar work[25];
36998a9c020eSBarry Smith     PetscInt    ipvt[5];
37008a9c020eSBarry Smith 
37018a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_5(values,ipvt,work,shift,allowzeropivot,&zeropivotdetected));
37028a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37038a9c020eSBarry Smith   }
37048a9c020eSBarry Smith     break;
37058a9c020eSBarry Smith   case 6:
37068a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_6(values,shift,allowzeropivot,&zeropivotdetected));
37078a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37088a9c020eSBarry Smith     break;
37098a9c020eSBarry Smith   case 7:
37108a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_7(values,shift,allowzeropivot,&zeropivotdetected));
37118a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37128a9c020eSBarry Smith     break;
37138a9c020eSBarry Smith   default:
37148a9c020eSBarry Smith   {
37158a9c020eSBarry Smith     PetscInt    *v_pivots,*IJ,j;
37168a9c020eSBarry Smith     PetscScalar *v_work;
37178a9c020eSBarry Smith 
37188a9c020eSBarry Smith     PetscCall(PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ));
37198a9c020eSBarry Smith     for (j=0; j<bs; j++) {
37208a9c020eSBarry Smith       IJ[j] = j;
37218a9c020eSBarry Smith     }
37228a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A(bs,values,v_pivots,v_work,allowzeropivot,&zeropivotdetected));
37238a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37248a9c020eSBarry Smith     PetscCall(PetscFree3(v_work,v_pivots,IJ));
37258a9c020eSBarry Smith   }
37268a9c020eSBarry Smith   }
37278a9c020eSBarry Smith   PetscFunctionReturn(0);
37288a9c020eSBarry Smith }
3729