xref: /petsc/src/mat/impls/dense/seq/dense.c (revision b965ef7f227f0b86e82ca189164bf258b1720295)
173f4d377SMatthew Knepley /*$Id: dense.c,v 1.208 2001/09/07 20:09:16 bsmith Exp $*/
267e560aaSBarry Smith /*
367e560aaSBarry Smith      Defines the basic matrix operations for sequential dense.
467e560aaSBarry Smith */
5289bc588SBarry Smith 
670f55243SBarry Smith #include "src/mat/impls/dense/seq/dense.h"
7b4c862e0SSatish Balay #include "petscblaslapack.h"
8289bc588SBarry Smith 
94a2ae208SSatish Balay #undef __FUNCT__
104a2ae208SSatish Balay #define __FUNCT__ "MatAXPY_SeqDense"
1187828ca2SBarry Smith int MatAXPY_SeqDense(PetscScalar *alpha,Mat X,Mat Y)
121987afe7SBarry Smith {
131987afe7SBarry Smith   Mat_SeqDense *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
14273d9f13SBarry Smith   int          N = X->m*X->n,one = 1;
153a40ed3dSBarry Smith 
163a40ed3dSBarry Smith   PetscFunctionBegin;
171987afe7SBarry Smith   BLaxpy_(&N,alpha,x->v,&one,y->v,&one);
18b0a32e0cSBarry Smith   PetscLogFlops(2*N-1);
193a40ed3dSBarry Smith   PetscFunctionReturn(0);
201987afe7SBarry Smith }
211987afe7SBarry Smith 
224a2ae208SSatish Balay #undef __FUNCT__
234a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqDense"
248f6be9afSLois Curfman McInnes int MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
25289bc588SBarry Smith {
264e220ebcSLois Curfman McInnes   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
27273d9f13SBarry Smith   int          i,N = A->m*A->n,count = 0;
2887828ca2SBarry Smith   PetscScalar  *v = a->v;
293a40ed3dSBarry Smith 
303a40ed3dSBarry Smith   PetscFunctionBegin;
31289bc588SBarry Smith   for (i=0; i<N; i++) {if (*v != 0.0) count++; v++;}
324e220ebcSLois Curfman McInnes 
33273d9f13SBarry Smith   info->rows_global       = (double)A->m;
34273d9f13SBarry Smith   info->columns_global    = (double)A->n;
35273d9f13SBarry Smith   info->rows_local        = (double)A->m;
36273d9f13SBarry Smith   info->columns_local     = (double)A->n;
374e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
384e220ebcSLois Curfman McInnes   info->nz_allocated      = (double)N;
394e220ebcSLois Curfman McInnes   info->nz_used           = (double)count;
404e220ebcSLois Curfman McInnes   info->nz_unneeded       = (double)(N-count);
414e220ebcSLois Curfman McInnes   info->assemblies        = (double)A->num_ass;
424e220ebcSLois Curfman McInnes   info->mallocs           = 0;
434e220ebcSLois Curfman McInnes   info->memory            = A->mem;
444e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
454e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
464e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
474e220ebcSLois Curfman McInnes 
483a40ed3dSBarry Smith   PetscFunctionReturn(0);
49289bc588SBarry Smith }
50289bc588SBarry Smith 
514a2ae208SSatish Balay #undef __FUNCT__
524a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqDense"
5387828ca2SBarry Smith int MatScale_SeqDense(PetscScalar *alpha,Mat A)
5480cd9d93SLois Curfman McInnes {
55273d9f13SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
5680cd9d93SLois Curfman McInnes   int          one = 1,nz;
5780cd9d93SLois Curfman McInnes 
583a40ed3dSBarry Smith   PetscFunctionBegin;
59273d9f13SBarry Smith   nz = A->m*A->n;
6080cd9d93SLois Curfman McInnes   BLscal_(&nz,alpha,a->v,&one);
61b0a32e0cSBarry Smith   PetscLogFlops(nz);
623a40ed3dSBarry Smith   PetscFunctionReturn(0);
6380cd9d93SLois Curfman McInnes }
6480cd9d93SLois Curfman McInnes 
65289bc588SBarry Smith /* ---------------------------------------------------------------*/
666831982aSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
676831982aSBarry Smith    rather than put it in the Mat->row slot.*/
684a2ae208SSatish Balay #undef __FUNCT__
694a2ae208SSatish Balay #define __FUNCT__ "MatLUFactor_SeqDense"
70e03a110bSBarry Smith int MatLUFactor_SeqDense(Mat A,IS row,IS col,MatLUInfo *minfo)
71289bc588SBarry Smith {
72c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
73b0a32e0cSBarry Smith   int          info,ierr;
7455659b69SBarry Smith 
753a40ed3dSBarry Smith   PetscFunctionBegin;
76289bc588SBarry Smith   if (!mat->pivots) {
77b0a32e0cSBarry Smith     ierr = PetscMalloc((A->m+1)*sizeof(int),&mat->pivots);CHKERRQ(ierr);
78b0a32e0cSBarry Smith     PetscLogObjectMemory(A,A->m*sizeof(int));
79289bc588SBarry Smith   }
80f1af5d2fSBarry Smith   A->factor = FACTOR_LU;
81273d9f13SBarry Smith   if (!A->m || !A->n) PetscFunctionReturn(0);
82ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRF)
83ae7cfcebSSatish Balay   SETERRQ(PETSC_ERR_SUP,"GETRF - Lapack routine is unavilable.");
84ae7cfcebSSatish Balay #else
85273d9f13SBarry Smith   LAgetrf_(&A->m,&A->n,mat->v,&A->m,mat->pivots,&info);
8629bbc08cSBarry Smith   if (info<0) SETERRQ(PETSC_ERR_LIB,"Bad argument to LU factorization");
8729bbc08cSBarry Smith   if (info>0) SETERRQ(PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
882ffef20aSBarry Smith #endif
89b0a32e0cSBarry Smith   PetscLogFlops((2*A->n*A->n*A->n)/3);
903a40ed3dSBarry Smith   PetscFunctionReturn(0);
91289bc588SBarry Smith }
926ee01492SSatish Balay 
934a2ae208SSatish Balay #undef __FUNCT__
944a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqDense"
955609ef8eSBarry Smith int MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
9602cad45dSBarry Smith {
9702cad45dSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data,*l;
9802cad45dSBarry Smith   int          ierr;
9902cad45dSBarry Smith   Mat          newi;
10002cad45dSBarry Smith 
1013a40ed3dSBarry Smith   PetscFunctionBegin;
102273d9f13SBarry Smith   ierr = MatCreateSeqDense(A->comm,A->m,A->n,PETSC_NULL,&newi);CHKERRQ(ierr);
10302cad45dSBarry Smith   l = (Mat_SeqDense*)newi->data;
1045609ef8eSBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
10587828ca2SBarry Smith     ierr = PetscMemcpy(l->v,mat->v,A->m*A->n*sizeof(PetscScalar));CHKERRQ(ierr);
10602cad45dSBarry Smith   }
10702cad45dSBarry Smith   newi->assembled = PETSC_TRUE;
10802cad45dSBarry Smith   *newmat = newi;
1093a40ed3dSBarry Smith   PetscFunctionReturn(0);
11002cad45dSBarry Smith }
11102cad45dSBarry Smith 
1124a2ae208SSatish Balay #undef __FUNCT__
1134a2ae208SSatish Balay #define __FUNCT__ "MatLUFactorSymbolic_SeqDense"
114e03a110bSBarry Smith int MatLUFactorSymbolic_SeqDense(Mat A,IS row,IS col,MatLUInfo *info,Mat *fact)
115289bc588SBarry Smith {
1163a40ed3dSBarry Smith   int ierr;
1173a40ed3dSBarry Smith 
1183a40ed3dSBarry Smith   PetscFunctionBegin;
1195609ef8eSBarry Smith   ierr = MatDuplicate_SeqDense(A,MAT_DO_NOT_COPY_VALUES,fact);CHKERRQ(ierr);
1203a40ed3dSBarry Smith   PetscFunctionReturn(0);
121289bc588SBarry Smith }
1226ee01492SSatish Balay 
1234a2ae208SSatish Balay #undef __FUNCT__
1244a2ae208SSatish Balay #define __FUNCT__ "MatLUFactorNumeric_SeqDense"
1258f6be9afSLois Curfman McInnes int MatLUFactorNumeric_SeqDense(Mat A,Mat *fact)
126289bc588SBarry Smith {
12702cad45dSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data,*l = (Mat_SeqDense*)(*fact)->data;
1283a40ed3dSBarry Smith   int          ierr;
1293a40ed3dSBarry Smith 
1303a40ed3dSBarry Smith   PetscFunctionBegin;
13102cad45dSBarry Smith   /* copy the numerical values */
13287828ca2SBarry Smith   ierr = PetscMemcpy(l->v,mat->v,A->m*A->n*sizeof(PetscScalar));CHKERRQ(ierr);
13302cad45dSBarry Smith   (*fact)->factor = 0;
134e03a110bSBarry Smith   ierr = MatLUFactor(*fact,0,0,PETSC_NULL);CHKERRQ(ierr);
1353a40ed3dSBarry Smith   PetscFunctionReturn(0);
136289bc588SBarry Smith }
1376ee01492SSatish Balay 
1384a2ae208SSatish Balay #undef __FUNCT__
1394a2ae208SSatish Balay #define __FUNCT__ "MatCholeskyFactorSymbolic_SeqDense"
140329f5518SBarry Smith int MatCholeskyFactorSymbolic_SeqDense(Mat A,IS row,PetscReal f,Mat *fact)
141289bc588SBarry Smith {
1423a40ed3dSBarry Smith   int ierr;
1433a40ed3dSBarry Smith 
1443a40ed3dSBarry Smith   PetscFunctionBegin;
1453a40ed3dSBarry Smith   ierr = MatConvert(A,MATSAME,fact);CHKERRQ(ierr);
1463a40ed3dSBarry Smith   PetscFunctionReturn(0);
147289bc588SBarry Smith }
1486ee01492SSatish Balay 
1494a2ae208SSatish Balay #undef __FUNCT__
1504a2ae208SSatish Balay #define __FUNCT__ "MatCholeskyFactor_SeqDense"
151329f5518SBarry Smith int MatCholeskyFactor_SeqDense(Mat A,IS perm,PetscReal f)
152289bc588SBarry Smith {
153c0bbcb79SLois Curfman McInnes   Mat_SeqDense  *mat = (Mat_SeqDense*)A->data;
154606d414cSSatish Balay   int           info,ierr;
15555659b69SBarry Smith 
1563a40ed3dSBarry Smith   PetscFunctionBegin;
157752f5567SLois Curfman McInnes   if (mat->pivots) {
158606d414cSSatish Balay     ierr = PetscFree(mat->pivots);CHKERRQ(ierr);
159b0a32e0cSBarry Smith     PetscLogObjectMemory(A,-A->m*sizeof(int));
160752f5567SLois Curfman McInnes     mat->pivots = 0;
161752f5567SLois Curfman McInnes   }
162273d9f13SBarry Smith   if (!A->m || !A->n) PetscFunctionReturn(0);
163ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRF)
164ae7cfcebSSatish Balay   SETERRQ(PETSC_ERR_SUP,"POTRF - Lapack routine is unavilable.");
165ae7cfcebSSatish Balay #else
166273d9f13SBarry Smith   LApotrf_("L",&A->n,mat->v,&A->m,&info);
16729bbc08cSBarry Smith   if (info) SETERRQ1(PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %d",info-1);
1682ffef20aSBarry Smith #endif
169c0bbcb79SLois Curfman McInnes   A->factor = FACTOR_CHOLESKY;
170b0a32e0cSBarry Smith   PetscLogFlops((A->n*A->n*A->n)/3);
1713a40ed3dSBarry Smith   PetscFunctionReturn(0);
172289bc588SBarry Smith }
173289bc588SBarry Smith 
1744a2ae208SSatish Balay #undef __FUNCT__
1750b4b3355SBarry Smith #define __FUNCT__ "MatCholeskyFactorNumeric_SeqDense"
1760b4b3355SBarry Smith int MatCholeskyFactorNumeric_SeqDense(Mat A,Mat *fact)
1770b4b3355SBarry Smith {
1780b4b3355SBarry Smith   int ierr;
1790b4b3355SBarry Smith 
1800b4b3355SBarry Smith   PetscFunctionBegin;
1810b4b3355SBarry Smith   ierr = MatCholeskyFactor_SeqDense(*fact,0,1.0);CHKERRQ(ierr);
1820b4b3355SBarry Smith   PetscFunctionReturn(0);
1830b4b3355SBarry Smith }
1840b4b3355SBarry Smith 
1850b4b3355SBarry Smith #undef __FUNCT__
1864a2ae208SSatish Balay #define __FUNCT__ "MatSolve_SeqDense"
1878f6be9afSLois Curfman McInnes int MatSolve_SeqDense(Mat A,Vec xx,Vec yy)
188289bc588SBarry Smith {
189c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
190a57ad546SLois Curfman McInnes   int          one = 1,info,ierr;
19187828ca2SBarry Smith   PetscScalar  *x,*y;
19267e560aaSBarry Smith 
1933a40ed3dSBarry Smith   PetscFunctionBegin;
194273d9f13SBarry Smith   if (!A->m || !A->n) PetscFunctionReturn(0);
1957a97a34bSBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
1967a97a34bSBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
19787828ca2SBarry Smith   ierr = PetscMemcpy(y,x,A->m*sizeof(PetscScalar));CHKERRQ(ierr);
198c0bbcb79SLois Curfman McInnes   if (A->factor == FACTOR_LU) {
199ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
200ae7cfcebSSatish Balay     SETERRQ(PETSC_ERR_SUP,"GETRS - Lapack routine is unavilable.");
201ae7cfcebSSatish Balay #else
202273d9f13SBarry Smith     LAgetrs_("N",&A->m,&one,mat->v,&A->m,mat->pivots,y,&A->m,&info);
2032ffef20aSBarry Smith     if (info) SETERRQ(PETSC_ERR_LIB,"MBad solve");
204ae7cfcebSSatish Balay #endif
2057a97a34bSBarry Smith   } else if (A->factor == FACTOR_CHOLESKY){
206ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
207ae7cfcebSSatish Balay     SETERRQ(PETSC_ERR_SUP,"POTRS - Lapack routine is unavilable.");
208ae7cfcebSSatish Balay #else
209273d9f13SBarry Smith     LApotrs_("L",&A->m,&one,mat->v,&A->m,y,&A->m,&info);
2102ffef20aSBarry Smith     if (info) SETERRQ(PETSC_ERR_LIB,"MBad solve");
211ae7cfcebSSatish Balay #endif
212289bc588SBarry Smith   }
21329bbc08cSBarry Smith   else SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
2147a97a34bSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
2157a97a34bSBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
216b0a32e0cSBarry Smith   PetscLogFlops(2*A->n*A->n - A->n);
2173a40ed3dSBarry Smith   PetscFunctionReturn(0);
218289bc588SBarry Smith }
2196ee01492SSatish Balay 
2204a2ae208SSatish Balay #undef __FUNCT__
2214a2ae208SSatish Balay #define __FUNCT__ "MatSolveTranspose_SeqDense"
2227c922b88SBarry Smith int MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy)
223da3a660dSBarry Smith {
224c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
2257a97a34bSBarry Smith   int          ierr,one = 1,info;
22687828ca2SBarry Smith   PetscScalar  *x,*y;
22767e560aaSBarry Smith 
2283a40ed3dSBarry Smith   PetscFunctionBegin;
229273d9f13SBarry Smith   if (!A->m || !A->n) PetscFunctionReturn(0);
2307a97a34bSBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
2317a97a34bSBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
23287828ca2SBarry Smith   ierr = PetscMemcpy(y,x,A->m*sizeof(PetscScalar));CHKERRQ(ierr);
233752f5567SLois Curfman McInnes   /* assume if pivots exist then use LU; else Cholesky */
234da3a660dSBarry Smith   if (mat->pivots) {
235ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
236ae7cfcebSSatish Balay     SETERRQ(PETSC_ERR_SUP,"GETRS - Lapack routine is unavilable.");
237ae7cfcebSSatish Balay #else
238273d9f13SBarry Smith     LAgetrs_("T",&A->m,&one,mat->v,&A->m,mat->pivots,y,&A->m,&info);
2392ffef20aSBarry Smith     if (info) SETERRQ(PETSC_ERR_LIB,"Bad solve");
240ae7cfcebSSatish Balay #endif
2417a97a34bSBarry Smith   } else {
242ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
243ae7cfcebSSatish Balay     SETERRQ(PETSC_ERR_SUP,"POTRS - Lapack routine is unavilable.");
244ae7cfcebSSatish Balay #else
245273d9f13SBarry Smith     LApotrs_("L",&A->m,&one,mat->v,&A->m,y,&A->m,&info);
2462ffef20aSBarry Smith     if (info) SETERRQ(PETSC_ERR_LIB,"Bad solve");
247ae7cfcebSSatish Balay #endif
248da3a660dSBarry Smith   }
2497a97a34bSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
2507a97a34bSBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
251b0a32e0cSBarry Smith   PetscLogFlops(2*A->n*A->n - A->n);
2523a40ed3dSBarry Smith   PetscFunctionReturn(0);
253da3a660dSBarry Smith }
2546ee01492SSatish Balay 
2554a2ae208SSatish Balay #undef __FUNCT__
2564a2ae208SSatish Balay #define __FUNCT__ "MatSolveAdd_SeqDense"
2578f6be9afSLois Curfman McInnes int MatSolveAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
258da3a660dSBarry Smith {
259c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
2607a97a34bSBarry Smith   int          ierr,one = 1,info;
26187828ca2SBarry Smith   PetscScalar  *x,*y,sone = 1.0;
262da3a660dSBarry Smith   Vec          tmp = 0;
26367e560aaSBarry Smith 
2643a40ed3dSBarry Smith   PetscFunctionBegin;
2657a97a34bSBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
2667a97a34bSBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
267273d9f13SBarry Smith   if (!A->m || !A->n) PetscFunctionReturn(0);
268da3a660dSBarry Smith   if (yy == zz) {
26978b31e54SBarry Smith     ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr);
270b0a32e0cSBarry Smith     PetscLogObjectParent(A,tmp);
27178b31e54SBarry Smith     ierr = VecCopy(yy,tmp);CHKERRQ(ierr);
272da3a660dSBarry Smith   }
27387828ca2SBarry Smith   ierr = PetscMemcpy(y,x,A->m*sizeof(PetscScalar));CHKERRQ(ierr);
274752f5567SLois Curfman McInnes   /* assume if pivots exist then use LU; else Cholesky */
275da3a660dSBarry Smith   if (mat->pivots) {
276ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
277ae7cfcebSSatish Balay     SETERRQ(PETSC_ERR_SUP,"GETRS - Lapack routine is unavilable.");
278ae7cfcebSSatish Balay #else
279273d9f13SBarry Smith     LAgetrs_("N",&A->m,&one,mat->v,&A->m,mat->pivots,y,&A->m,&info);
2802ffef20aSBarry Smith     if (info) SETERRQ(PETSC_ERR_LIB,"Bad solve");
281ae7cfcebSSatish Balay #endif
282a8c6a408SBarry Smith   } else {
283ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
284ae7cfcebSSatish Balay     SETERRQ(PETSC_ERR_SUP,"POTRS - Lapack routine is unavilable.");
285ae7cfcebSSatish Balay #else
286273d9f13SBarry Smith     LApotrs_("L",&A->m,&one,mat->v,&A->m,y,&A->m,&info);
2872ffef20aSBarry Smith     if (info) SETERRQ(PETSC_ERR_LIB,"Bad solve");
288ae7cfcebSSatish Balay #endif
289da3a660dSBarry Smith   }
290a8c6a408SBarry Smith   if (tmp) {ierr = VecAXPY(&sone,tmp,yy);CHKERRQ(ierr); ierr = VecDestroy(tmp);CHKERRQ(ierr);}
291a8c6a408SBarry Smith   else     {ierr = VecAXPY(&sone,zz,yy);CHKERRQ(ierr);}
2927a97a34bSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
2937a97a34bSBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
294b0a32e0cSBarry Smith   PetscLogFlops(2*A->n*A->n);
2953a40ed3dSBarry Smith   PetscFunctionReturn(0);
296da3a660dSBarry Smith }
29767e560aaSBarry Smith 
2984a2ae208SSatish Balay #undef __FUNCT__
2994a2ae208SSatish Balay #define __FUNCT__ "MatSolveTransposeAdd_SeqDense"
3007c922b88SBarry Smith int MatSolveTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
301da3a660dSBarry Smith {
302c0bbcb79SLois Curfman McInnes   Mat_SeqDense  *mat = (Mat_SeqDense*)A->data;
3036abc6512SBarry Smith   int           one = 1,info,ierr;
30487828ca2SBarry Smith   PetscScalar   *x,*y,sone = 1.0;
305da3a660dSBarry Smith   Vec           tmp;
30667e560aaSBarry Smith 
3073a40ed3dSBarry Smith   PetscFunctionBegin;
308273d9f13SBarry Smith   if (!A->m || !A->n) PetscFunctionReturn(0);
3097a97a34bSBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
3107a97a34bSBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
311da3a660dSBarry Smith   if (yy == zz) {
31278b31e54SBarry Smith     ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr);
313b0a32e0cSBarry Smith     PetscLogObjectParent(A,tmp);
31478b31e54SBarry Smith     ierr = VecCopy(yy,tmp);CHKERRQ(ierr);
315da3a660dSBarry Smith   }
31687828ca2SBarry Smith   ierr = PetscMemcpy(y,x,A->m*sizeof(PetscScalar));CHKERRQ(ierr);
317752f5567SLois Curfman McInnes   /* assume if pivots exist then use LU; else Cholesky */
318da3a660dSBarry Smith   if (mat->pivots) {
319ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS)
320ae7cfcebSSatish Balay     SETERRQ(PETSC_ERR_SUP,"GETRS - Lapack routine is unavilable.");
321ae7cfcebSSatish Balay #else
322273d9f13SBarry Smith     LAgetrs_("T",&A->m,&one,mat->v,&A->m,mat->pivots,y,&A->m,&info);
3232ffef20aSBarry Smith     if (info) SETERRQ(PETSC_ERR_LIB,"Bad solve");
324ae7cfcebSSatish Balay #endif
3253a40ed3dSBarry Smith   } else {
326ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS)
327ae7cfcebSSatish Balay     SETERRQ(PETSC_ERR_SUP,"POTRS - Lapack routine is unavilable.");
328ae7cfcebSSatish Balay #else
329273d9f13SBarry Smith     LApotrs_("L",&A->m,&one,mat->v,&A->m,y,&A->m,&info);
3302ffef20aSBarry Smith     if (info) SETERRQ(PETSC_ERR_LIB,"Bad solve");
331ae7cfcebSSatish Balay #endif
332da3a660dSBarry Smith   }
33390f02eecSBarry Smith   if (tmp) {
33490f02eecSBarry Smith     ierr = VecAXPY(&sone,tmp,yy);CHKERRQ(ierr);
33590f02eecSBarry Smith     ierr = VecDestroy(tmp);CHKERRQ(ierr);
3363a40ed3dSBarry Smith   } else {
33790f02eecSBarry Smith     ierr = VecAXPY(&sone,zz,yy);CHKERRQ(ierr);
33890f02eecSBarry Smith   }
3397a97a34bSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
3407a97a34bSBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
341b0a32e0cSBarry Smith   PetscLogFlops(2*A->n*A->n);
3423a40ed3dSBarry Smith   PetscFunctionReturn(0);
343da3a660dSBarry Smith }
344289bc588SBarry Smith /* ------------------------------------------------------------------*/
3454a2ae208SSatish Balay #undef __FUNCT__
3464a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqDense"
347329f5518SBarry Smith int MatRelax_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,
348c14dc6b6SHong Zhang                           PetscReal shift,int its,int lits,Vec xx)
349289bc588SBarry Smith {
350c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
35187828ca2SBarry Smith   PetscScalar  *x,*b,*v = mat->v,zero = 0.0,xt;
352273d9f13SBarry Smith   int          ierr,m = A->m,i;
353aa482453SBarry Smith #if !defined(PETSC_USE_COMPLEX)
354bc1b551cSSatish Balay   int          o = 1;
355bc1b551cSSatish Balay #endif
356289bc588SBarry Smith 
3573a40ed3dSBarry Smith   PetscFunctionBegin;
358289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
3593a40ed3dSBarry Smith     /* this is a hack fix, should have another version without the second BLdot */
360bbb6d6a8SBarry Smith     ierr = VecSet(&zero,xx);CHKERRQ(ierr);
361289bc588SBarry Smith   }
3627a97a34bSBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
3637a97a34bSBarry Smith   ierr = VecGetArray(bb,&b);CHKERRQ(ierr);
364*b965ef7fSBarry Smith   its  = its*lits;
365289bc588SBarry Smith   while (its--) {
366289bc588SBarry Smith     if (flag & SOR_FORWARD_SWEEP){
367289bc588SBarry Smith       for (i=0; i<m; i++) {
368aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
369f1747703SBarry Smith         /* cannot use BLAS dot for complex because compiler/linker is
370f1747703SBarry Smith            not happy about returning a double complex */
371f1747703SBarry Smith         int         _i;
37287828ca2SBarry Smith         PetscScalar sum = b[i];
373f1747703SBarry Smith         for (_i=0; _i<m; _i++) {
3743f6de6efSSatish Balay           sum -= PetscConj(v[i+_i*m])*x[_i];
375f1747703SBarry Smith         }
376f1747703SBarry Smith         xt = sum;
377f1747703SBarry Smith #else
378289bc588SBarry Smith         xt = b[i]-BLdot_(&m,v+i,&m,x,&o);
379f1747703SBarry Smith #endif
38055a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
381289bc588SBarry Smith       }
382289bc588SBarry Smith     }
383289bc588SBarry Smith     if (flag & SOR_BACKWARD_SWEEP) {
384289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
385aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
386f1747703SBarry Smith         /* cannot use BLAS dot for complex because compiler/linker is
387f1747703SBarry Smith            not happy about returning a double complex */
388f1747703SBarry Smith         int         _i;
38987828ca2SBarry Smith         PetscScalar sum = b[i];
390f1747703SBarry Smith         for (_i=0; _i<m; _i++) {
3913f6de6efSSatish Balay           sum -= PetscConj(v[i+_i*m])*x[_i];
392f1747703SBarry Smith         }
393f1747703SBarry Smith         xt = sum;
394f1747703SBarry Smith #else
395289bc588SBarry Smith         xt = b[i]-BLdot_(&m,v+i,&m,x,&o);
396f1747703SBarry Smith #endif
39755a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
398289bc588SBarry Smith       }
399289bc588SBarry Smith     }
400289bc588SBarry Smith   }
401600d6d0bSBarry Smith   ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);
4027a97a34bSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
4033a40ed3dSBarry Smith   PetscFunctionReturn(0);
404289bc588SBarry Smith }
405289bc588SBarry Smith 
406289bc588SBarry Smith /* -----------------------------------------------------------------*/
4074a2ae208SSatish Balay #undef __FUNCT__
4084a2ae208SSatish Balay #define __FUNCT__ "MatMultTranspose_SeqDense"
4097c922b88SBarry Smith int MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
410289bc588SBarry Smith {
411c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
41287828ca2SBarry Smith   PetscScalar  *v = mat->v,*x,*y;
413ea709b57SSatish Balay   int          ierr,_One=1;
414ea709b57SSatish Balay   PetscScalar  _DOne=1.0,_DZero=0.0;
4153a40ed3dSBarry Smith 
4163a40ed3dSBarry Smith   PetscFunctionBegin;
417273d9f13SBarry Smith   if (!A->m || !A->n) PetscFunctionReturn(0);
4187a97a34bSBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
4197a97a34bSBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
420273d9f13SBarry Smith   LAgemv_("T",&(A->m),&(A->n),&_DOne,v,&(A->m),x,&_One,&_DZero,y,&_One);
4217a97a34bSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
4227a97a34bSBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
423b0a32e0cSBarry Smith   PetscLogFlops(2*A->m*A->n - A->n);
4243a40ed3dSBarry Smith   PetscFunctionReturn(0);
425289bc588SBarry Smith }
4266ee01492SSatish Balay 
4274a2ae208SSatish Balay #undef __FUNCT__
4284a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqDense"
42944cd7ae7SLois Curfman McInnes int MatMult_SeqDense(Mat A,Vec xx,Vec yy)
430289bc588SBarry Smith {
431c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
43287828ca2SBarry Smith   PetscScalar  *v = mat->v,*x,*y,_DOne=1.0,_DZero=0.0;
433329f5518SBarry Smith   int          ierr,_One=1;
4343a40ed3dSBarry Smith 
4353a40ed3dSBarry Smith   PetscFunctionBegin;
436273d9f13SBarry Smith   if (!A->m || !A->n) PetscFunctionReturn(0);
4377a97a34bSBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
4387a97a34bSBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
439273d9f13SBarry Smith   LAgemv_("N",&(A->m),&(A->n),&_DOne,v,&(A->m),x,&_One,&_DZero,y,&_One);
4407a97a34bSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
4417a97a34bSBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
442b0a32e0cSBarry Smith   PetscLogFlops(2*A->m*A->n - A->m);
4433a40ed3dSBarry Smith   PetscFunctionReturn(0);
444289bc588SBarry Smith }
4456ee01492SSatish Balay 
4464a2ae208SSatish Balay #undef __FUNCT__
4474a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqDense"
44844cd7ae7SLois Curfman McInnes int MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
449289bc588SBarry Smith {
450c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
45187828ca2SBarry Smith   PetscScalar  *v = mat->v,*x,*y,_DOne=1.0;
452329f5518SBarry Smith   int          ierr,_One=1;
4533a40ed3dSBarry Smith 
4543a40ed3dSBarry Smith   PetscFunctionBegin;
455273d9f13SBarry Smith   if (!A->m || !A->n) PetscFunctionReturn(0);
456600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
4577a97a34bSBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
4587a97a34bSBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
459273d9f13SBarry Smith   LAgemv_("N",&(A->m),&(A->n),&_DOne,v,&(A->m),x,&_One,&_DOne,y,&_One);
4607a97a34bSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
4617a97a34bSBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
462b0a32e0cSBarry Smith   PetscLogFlops(2*A->m*A->n);
4633a40ed3dSBarry Smith   PetscFunctionReturn(0);
464289bc588SBarry Smith }
4656ee01492SSatish Balay 
4664a2ae208SSatish Balay #undef __FUNCT__
4674a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqDense"
4687c922b88SBarry Smith int MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
469289bc588SBarry Smith {
470c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
47187828ca2SBarry Smith   PetscScalar  *v = mat->v,*x,*y;
4727a97a34bSBarry Smith   int          ierr,_One=1;
47387828ca2SBarry Smith   PetscScalar  _DOne=1.0;
4743a40ed3dSBarry Smith 
4753a40ed3dSBarry Smith   PetscFunctionBegin;
476273d9f13SBarry Smith   if (!A->m || !A->n) PetscFunctionReturn(0);
477600d6d0bSBarry Smith   if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);}
4787a97a34bSBarry Smith   ierr = VecGetArray(xx,&x);CHKERRQ(ierr);
4797a97a34bSBarry Smith   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
480273d9f13SBarry Smith   LAgemv_("T",&(A->m),&(A->n),&_DOne,v,&(A->m),x,&_One,&_DOne,y,&_One);
4817a97a34bSBarry Smith   ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr);
4827a97a34bSBarry Smith   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
483b0a32e0cSBarry Smith   PetscLogFlops(2*A->m*A->n);
4843a40ed3dSBarry Smith   PetscFunctionReturn(0);
485289bc588SBarry Smith }
486289bc588SBarry Smith 
487289bc588SBarry Smith /* -----------------------------------------------------------------*/
4884a2ae208SSatish Balay #undef __FUNCT__
4894a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqDense"
49087828ca2SBarry Smith int MatGetRow_SeqDense(Mat A,int row,int *ncols,int **cols,PetscScalar **vals)
491289bc588SBarry Smith {
492c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
49387828ca2SBarry Smith   PetscScalar  *v;
494b0a32e0cSBarry Smith   int          i,ierr;
49567e560aaSBarry Smith 
4963a40ed3dSBarry Smith   PetscFunctionBegin;
497273d9f13SBarry Smith   *ncols = A->n;
498289bc588SBarry Smith   if (cols) {
499b0a32e0cSBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(int),cols);CHKERRQ(ierr);
500273d9f13SBarry Smith     for (i=0; i<A->n; i++) (*cols)[i] = i;
501289bc588SBarry Smith   }
502289bc588SBarry Smith   if (vals) {
50387828ca2SBarry Smith     ierr = PetscMalloc((A->n+1)*sizeof(PetscScalar),vals);CHKERRQ(ierr);
504289bc588SBarry Smith     v    = mat->v + row;
505273d9f13SBarry Smith     for (i=0; i<A->n; i++) {(*vals)[i] = *v; v += A->m;}
506289bc588SBarry Smith   }
5073a40ed3dSBarry Smith   PetscFunctionReturn(0);
508289bc588SBarry Smith }
5096ee01492SSatish Balay 
5104a2ae208SSatish Balay #undef __FUNCT__
5114a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqDense"
51287828ca2SBarry Smith int MatRestoreRow_SeqDense(Mat A,int row,int *ncols,int **cols,PetscScalar **vals)
513289bc588SBarry Smith {
514606d414cSSatish Balay   int ierr;
515606d414cSSatish Balay   PetscFunctionBegin;
516606d414cSSatish Balay   if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);}
517606d414cSSatish Balay   if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); }
5183a40ed3dSBarry Smith   PetscFunctionReturn(0);
519289bc588SBarry Smith }
520289bc588SBarry Smith /* ----------------------------------------------------------------*/
5214a2ae208SSatish Balay #undef __FUNCT__
5224a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqDense"
5238f6be9afSLois Curfman McInnes int MatSetValues_SeqDense(Mat A,int m,int *indexm,int n,
52487828ca2SBarry Smith                                     int *indexn,PetscScalar *v,InsertMode addv)
525289bc588SBarry Smith {
526c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
527289bc588SBarry Smith   int          i,j;
528d6dfbf8fSBarry Smith 
5293a40ed3dSBarry Smith   PetscFunctionBegin;
530289bc588SBarry Smith   if (!mat->roworiented) {
531dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
532289bc588SBarry Smith       for (j=0; j<n; j++) {
5335ef9f2a5SBarry Smith         if (indexn[j] < 0) {v += m; continue;}
534aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
53529bbc08cSBarry Smith         if (indexn[j] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
53658804f6dSBarry Smith #endif
537289bc588SBarry Smith         for (i=0; i<m; i++) {
5385ef9f2a5SBarry Smith           if (indexm[i] < 0) {v++; continue;}
539aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
54029bbc08cSBarry Smith           if (indexm[i] >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
54158804f6dSBarry Smith #endif
542273d9f13SBarry Smith           mat->v[indexn[j]*A->m + indexm[i]] = *v++;
543289bc588SBarry Smith         }
544289bc588SBarry Smith       }
5453a40ed3dSBarry Smith     } else {
546289bc588SBarry Smith       for (j=0; j<n; j++) {
5475ef9f2a5SBarry Smith         if (indexn[j] < 0) {v += m; continue;}
548aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
54929bbc08cSBarry Smith         if (indexn[j] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
55058804f6dSBarry Smith #endif
551289bc588SBarry Smith         for (i=0; i<m; i++) {
5525ef9f2a5SBarry Smith           if (indexm[i] < 0) {v++; continue;}
553aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
55429bbc08cSBarry Smith           if (indexm[i] >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
55558804f6dSBarry Smith #endif
556273d9f13SBarry Smith           mat->v[indexn[j]*A->m + indexm[i]] += *v++;
557289bc588SBarry Smith         }
558289bc588SBarry Smith       }
559289bc588SBarry Smith     }
5603a40ed3dSBarry Smith   } else {
561dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
562e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
5635ef9f2a5SBarry Smith         if (indexm[i] < 0) { v += n; continue;}
564aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
56529bbc08cSBarry Smith         if (indexm[i] >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
56658804f6dSBarry Smith #endif
567e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
5685ef9f2a5SBarry Smith           if (indexn[j] < 0) { v++; continue;}
569aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
57029bbc08cSBarry Smith           if (indexn[j] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
57158804f6dSBarry Smith #endif
572273d9f13SBarry Smith           mat->v[indexn[j]*A->m + indexm[i]] = *v++;
573e8d4e0b9SBarry Smith         }
574e8d4e0b9SBarry Smith       }
5753a40ed3dSBarry Smith     } else {
576289bc588SBarry Smith       for (i=0; i<m; i++) {
5775ef9f2a5SBarry Smith         if (indexm[i] < 0) { v += n; continue;}
578aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
57929bbc08cSBarry Smith         if (indexm[i] >= A->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Row too large");
58058804f6dSBarry Smith #endif
581289bc588SBarry Smith         for (j=0; j<n; j++) {
5825ef9f2a5SBarry Smith           if (indexn[j] < 0) { v++; continue;}
583aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g)
58429bbc08cSBarry Smith           if (indexn[j] >= A->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Column too large");
58558804f6dSBarry Smith #endif
586273d9f13SBarry Smith           mat->v[indexn[j]*A->m + indexm[i]] += *v++;
587289bc588SBarry Smith         }
588289bc588SBarry Smith       }
589289bc588SBarry Smith     }
590e8d4e0b9SBarry Smith   }
5913a40ed3dSBarry Smith   PetscFunctionReturn(0);
592289bc588SBarry Smith }
593e8d4e0b9SBarry Smith 
5944a2ae208SSatish Balay #undef __FUNCT__
5954a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqDense"
59687828ca2SBarry Smith int MatGetValues_SeqDense(Mat A,int m,int *indexm,int n,int *indexn,PetscScalar *v)
597ae80bb75SLois Curfman McInnes {
598ae80bb75SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
599ae80bb75SLois Curfman McInnes   int          i,j;
60087828ca2SBarry Smith   PetscScalar  *vpt = v;
601ae80bb75SLois Curfman McInnes 
6023a40ed3dSBarry Smith   PetscFunctionBegin;
603ae80bb75SLois Curfman McInnes   /* row-oriented output */
604ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
605ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
606273d9f13SBarry Smith       *vpt++ = mat->v[indexn[j]*A->m + indexm[i]];
607ae80bb75SLois Curfman McInnes     }
608ae80bb75SLois Curfman McInnes   }
6093a40ed3dSBarry Smith   PetscFunctionReturn(0);
610ae80bb75SLois Curfman McInnes }
611ae80bb75SLois Curfman McInnes 
612289bc588SBarry Smith /* -----------------------------------------------------------------*/
613289bc588SBarry Smith 
614e090d566SSatish Balay #include "petscsys.h"
61588e32edaSLois Curfman McInnes 
616273d9f13SBarry Smith EXTERN_C_BEGIN
6174a2ae208SSatish Balay #undef __FUNCT__
6184a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqDense"
619b0a32e0cSBarry Smith int MatLoad_SeqDense(PetscViewer viewer,MatType type,Mat *A)
62088e32edaSLois Curfman McInnes {
62188e32edaSLois Curfman McInnes   Mat_SeqDense *a;
62288e32edaSLois Curfman McInnes   Mat          B;
62388e32edaSLois Curfman McInnes   int          *scols,i,j,nz,ierr,fd,header[4],size;
62488e32edaSLois Curfman McInnes   int          *rowlengths = 0,M,N,*cols;
62587828ca2SBarry Smith   PetscScalar  *vals,*svals,*v,*w;
62619bcc07fSBarry Smith   MPI_Comm     comm = ((PetscObject)viewer)->comm;
62788e32edaSLois Curfman McInnes 
6283a40ed3dSBarry Smith   PetscFunctionBegin;
629d132466eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
63029bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"view must have one processor");
631b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
6320752156aSBarry Smith   ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr);
633552e946dSBarry Smith   if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Not matrix object");
63488e32edaSLois Curfman McInnes   M = header[1]; N = header[2]; nz = header[3];
63588e32edaSLois Curfman McInnes 
63690ace30eSBarry Smith   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense */
63790ace30eSBarry Smith     ierr = MatCreateSeqDense(comm,M,N,PETSC_NULL,A);CHKERRQ(ierr);
63890ace30eSBarry Smith     B    = *A;
63990ace30eSBarry Smith     a    = (Mat_SeqDense*)B->data;
6404a41a4d3SSatish Balay     v    = a->v;
6414a41a4d3SSatish Balay     /* Allocate some temp space to read in the values and then flip them
6424a41a4d3SSatish Balay        from row major to column major */
64387828ca2SBarry Smith     ierr = PetscMalloc((M*N+1)*sizeof(PetscScalar),&w);CHKERRQ(ierr);
64490ace30eSBarry Smith     /* read in nonzero values */
6454a41a4d3SSatish Balay     ierr = PetscBinaryRead(fd,w,M*N,PETSC_SCALAR);CHKERRQ(ierr);
6464a41a4d3SSatish Balay     /* now flip the values and store them in the matrix*/
6474a41a4d3SSatish Balay     for (j=0; j<N; j++) {
6484a41a4d3SSatish Balay       for (i=0; i<M; i++) {
6494a41a4d3SSatish Balay         *v++ =w[i*N+j];
6504a41a4d3SSatish Balay       }
6514a41a4d3SSatish Balay     }
652606d414cSSatish Balay     ierr = PetscFree(w);CHKERRQ(ierr);
6536d4a8577SBarry Smith     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
6546d4a8577SBarry Smith     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
65590ace30eSBarry Smith   } else {
65688e32edaSLois Curfman McInnes     /* read row lengths */
657b0a32e0cSBarry Smith     ierr = PetscMalloc((M+1)*sizeof(int),&rowlengths);CHKERRQ(ierr);
6580752156aSBarry Smith     ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr);
65988e32edaSLois Curfman McInnes 
66088e32edaSLois Curfman McInnes     /* create our matrix */
661b4fd4287SBarry Smith     ierr = MatCreateSeqDense(comm,M,N,PETSC_NULL,A);CHKERRQ(ierr);
66288e32edaSLois Curfman McInnes     B = *A;
66388e32edaSLois Curfman McInnes     a = (Mat_SeqDense*)B->data;
66488e32edaSLois Curfman McInnes     v = a->v;
66588e32edaSLois Curfman McInnes 
66688e32edaSLois Curfman McInnes     /* read column indices and nonzeros */
667b0a32e0cSBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(int),&scols);CHKERRQ(ierr);
668b0a32e0cSBarry Smith     cols = scols;
6690752156aSBarry Smith     ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT);CHKERRQ(ierr);
67087828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&svals);CHKERRQ(ierr);
671b0a32e0cSBarry Smith     vals = svals;
6720752156aSBarry Smith     ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR);CHKERRQ(ierr);
67388e32edaSLois Curfman McInnes 
67488e32edaSLois Curfman McInnes     /* insert into matrix */
67588e32edaSLois Curfman McInnes     for (i=0; i<M; i++) {
67688e32edaSLois Curfman McInnes       for (j=0; j<rowlengths[i]; j++) v[i+M*scols[j]] = svals[j];
67788e32edaSLois Curfman McInnes       svals += rowlengths[i]; scols += rowlengths[i];
67888e32edaSLois Curfman McInnes     }
679606d414cSSatish Balay     ierr = PetscFree(vals);CHKERRQ(ierr);
680606d414cSSatish Balay     ierr = PetscFree(cols);CHKERRQ(ierr);
681606d414cSSatish Balay     ierr = PetscFree(rowlengths);CHKERRQ(ierr);
68288e32edaSLois Curfman McInnes 
6836d4a8577SBarry Smith     ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
6846d4a8577SBarry Smith     ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
68590ace30eSBarry Smith   }
6863a40ed3dSBarry Smith   PetscFunctionReturn(0);
68788e32edaSLois Curfman McInnes }
688273d9f13SBarry Smith EXTERN_C_END
68988e32edaSLois Curfman McInnes 
690e090d566SSatish Balay #include "petscsys.h"
691932b0c3eSLois Curfman McInnes 
6924a2ae208SSatish Balay #undef __FUNCT__
6934a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqDense_ASCII"
694b0a32e0cSBarry Smith static int MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
695289bc588SBarry Smith {
696932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
697fb9695e5SSatish Balay   int               ierr,i,j;
698fb9695e5SSatish Balay   char              *name;
69987828ca2SBarry Smith   PetscScalar       *v;
700f3ef73ceSBarry Smith   PetscViewerFormat format;
701932b0c3eSLois Curfman McInnes 
7023a40ed3dSBarry Smith   PetscFunctionBegin;
703435da068SBarry Smith   ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
704b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
705fb9695e5SSatish Balay   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_LONG) {
7063a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
707fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
708b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
709273d9f13SBarry Smith     for (i=0; i<A->m; i++) {
71044cd7ae7SLois Curfman McInnes       v = a->v + i;
711b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr);
712273d9f13SBarry Smith       for (j=0; j<A->n; j++) {
713aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
714329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
715b0a32e0cSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %d %g + %g i",j,PetscRealPart(*v),PetscImaginaryPart(*v));CHKERRQ(ierr);
716329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
717b0a32e0cSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %d %g ",j,PetscRealPart(*v));CHKERRQ(ierr);
7186831982aSBarry Smith         }
71980cd9d93SLois Curfman McInnes #else
7206831982aSBarry Smith         if (*v) {
721b0a32e0cSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer," %d %g ",j,*v);CHKERRQ(ierr);
7226831982aSBarry Smith         }
72380cd9d93SLois Curfman McInnes #endif
724273d9f13SBarry Smith         v += A->m;
72580cd9d93SLois Curfman McInnes       }
726b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
72780cd9d93SLois Curfman McInnes     }
728b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
7293a40ed3dSBarry Smith   } else {
730b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr);
731aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
732ffac6cdbSBarry Smith     PetscTruth allreal = PETSC_TRUE;
73347989497SBarry Smith     /* determine if matrix has all real values */
73447989497SBarry Smith     v = a->v;
735273d9f13SBarry Smith     for (i=0; i<A->m*A->n; i++) {
736ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break ;}
73747989497SBarry Smith     }
73847989497SBarry Smith #endif
739fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
7403a7fca6bSBarry Smith       ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr);
741b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %d %d \n",A->m,A->n);CHKERRQ(ierr);
742fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%d,%d);\n",name,A->m,A->n);CHKERRQ(ierr);
743fb9695e5SSatish Balay       ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr);
744ffac6cdbSBarry Smith     }
745ffac6cdbSBarry Smith 
746273d9f13SBarry Smith     for (i=0; i<A->m; i++) {
747932b0c3eSLois Curfman McInnes       v = a->v + i;
748273d9f13SBarry Smith       for (j=0; j<A->n; j++) {
749aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
75047989497SBarry Smith         if (allreal) {
751b0a32e0cSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%6.4e ",PetscRealPart(*v));CHKERRQ(ierr); v += A->m;
75247989497SBarry Smith         } else {
753b0a32e0cSBarry Smith           ierr = PetscViewerASCIIPrintf(viewer,"%6.4e + %6.4e i ",PetscRealPart(*v),PetscImaginaryPart(*v));CHKERRQ(ierr); v += A->m;
75447989497SBarry Smith         }
755289bc588SBarry Smith #else
756b0a32e0cSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"%6.4e ",*v);CHKERRQ(ierr); v += A->m;
757289bc588SBarry Smith #endif
758289bc588SBarry Smith       }
759b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr);
760289bc588SBarry Smith     }
761fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
762b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr);
763ffac6cdbSBarry Smith     }
764b0a32e0cSBarry Smith     ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr);
765da3a660dSBarry Smith   }
766b0a32e0cSBarry Smith   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
7673a40ed3dSBarry Smith   PetscFunctionReturn(0);
768289bc588SBarry Smith }
769289bc588SBarry Smith 
7704a2ae208SSatish Balay #undef __FUNCT__
7714a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqDense_Binary"
772b0a32e0cSBarry Smith static int MatView_SeqDense_Binary(Mat A,PetscViewer viewer)
773932b0c3eSLois Curfman McInnes {
774932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
775273d9f13SBarry Smith   int               ict,j,n = A->n,m = A->m,i,fd,*col_lens,ierr,nz = m*n;
77687828ca2SBarry Smith   PetscScalar       *v,*anonz,*vals;
777f3ef73ceSBarry Smith   PetscViewerFormat format;
778932b0c3eSLois Curfman McInnes 
7793a40ed3dSBarry Smith   PetscFunctionBegin;
780b0a32e0cSBarry Smith   ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr);
78190ace30eSBarry Smith 
782b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
783fb9695e5SSatish Balay   if (format == PETSC_VIEWER_BINARY_NATIVE) {
78490ace30eSBarry Smith     /* store the matrix as a dense matrix */
785b0a32e0cSBarry Smith     ierr = PetscMalloc(4*sizeof(int),&col_lens);CHKERRQ(ierr);
786552e946dSBarry Smith     col_lens[0] = MAT_FILE_COOKIE;
78790ace30eSBarry Smith     col_lens[1] = m;
78890ace30eSBarry Smith     col_lens[2] = n;
78990ace30eSBarry Smith     col_lens[3] = MATRIX_BINARY_FORMAT_DENSE;
7900752156aSBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,4,PETSC_INT,1);CHKERRQ(ierr);
791606d414cSSatish Balay     ierr = PetscFree(col_lens);CHKERRQ(ierr);
79290ace30eSBarry Smith 
79390ace30eSBarry Smith     /* write out matrix, by rows */
79487828ca2SBarry Smith     ierr = PetscMalloc((m*n+1)*sizeof(PetscScalar),&vals);CHKERRQ(ierr);
79590ace30eSBarry Smith     v    = a->v;
79690ace30eSBarry Smith     for (i=0; i<m; i++) {
79790ace30eSBarry Smith       for (j=0; j<n; j++) {
79890ace30eSBarry Smith         vals[i + j*m] = *v++;
79990ace30eSBarry Smith       }
80090ace30eSBarry Smith     }
8010752156aSBarry Smith     ierr = PetscBinaryWrite(fd,vals,n*m,PETSC_SCALAR,0);CHKERRQ(ierr);
802606d414cSSatish Balay     ierr = PetscFree(vals);CHKERRQ(ierr);
80390ace30eSBarry Smith   } else {
804b0a32e0cSBarry Smith     ierr = PetscMalloc((4+nz)*sizeof(int),&col_lens);CHKERRQ(ierr);
805552e946dSBarry Smith     col_lens[0] = MAT_FILE_COOKIE;
806932b0c3eSLois Curfman McInnes     col_lens[1] = m;
807932b0c3eSLois Curfman McInnes     col_lens[2] = n;
808932b0c3eSLois Curfman McInnes     col_lens[3] = nz;
809932b0c3eSLois Curfman McInnes 
810932b0c3eSLois Curfman McInnes     /* store lengths of each row and write (including header) to file */
811932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) col_lens[4+i] = n;
8120752156aSBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,4+m,PETSC_INT,1);CHKERRQ(ierr);
813932b0c3eSLois Curfman McInnes 
814932b0c3eSLois Curfman McInnes     /* Possibly should write in smaller increments, not whole matrix at once? */
815932b0c3eSLois Curfman McInnes     /* store column indices (zero start index) */
816932b0c3eSLois Curfman McInnes     ict = 0;
817932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
818932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) col_lens[ict++] = j;
819932b0c3eSLois Curfman McInnes     }
8200752156aSBarry Smith     ierr = PetscBinaryWrite(fd,col_lens,nz,PETSC_INT,0);CHKERRQ(ierr);
821606d414cSSatish Balay     ierr = PetscFree(col_lens);CHKERRQ(ierr);
822932b0c3eSLois Curfman McInnes 
823932b0c3eSLois Curfman McInnes     /* store nonzero values */
82487828ca2SBarry Smith     ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&anonz);CHKERRQ(ierr);
825932b0c3eSLois Curfman McInnes     ict  = 0;
826932b0c3eSLois Curfman McInnes     for (i=0; i<m; i++) {
827932b0c3eSLois Curfman McInnes       v = a->v + i;
828932b0c3eSLois Curfman McInnes       for (j=0; j<n; j++) {
829273d9f13SBarry Smith         anonz[ict++] = *v; v += A->m;
830932b0c3eSLois Curfman McInnes       }
831932b0c3eSLois Curfman McInnes     }
8320752156aSBarry Smith     ierr = PetscBinaryWrite(fd,anonz,nz,PETSC_SCALAR,0);CHKERRQ(ierr);
833606d414cSSatish Balay     ierr = PetscFree(anonz);CHKERRQ(ierr);
83490ace30eSBarry Smith   }
8353a40ed3dSBarry Smith   PetscFunctionReturn(0);
836932b0c3eSLois Curfman McInnes }
837932b0c3eSLois Curfman McInnes 
8384a2ae208SSatish Balay #undef __FUNCT__
8394a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqDense_Draw_Zoom"
840b0a32e0cSBarry Smith int MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
841f1af5d2fSBarry Smith {
842f1af5d2fSBarry Smith   Mat               A = (Mat) Aa;
843f1af5d2fSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
844fb9695e5SSatish Balay   int               m = A->m,n = A->n,color,i,j,ierr;
84587828ca2SBarry Smith   PetscScalar       *v = a->v;
846b0a32e0cSBarry Smith   PetscViewer       viewer;
847b0a32e0cSBarry Smith   PetscDraw         popup;
848329f5518SBarry Smith   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r,scale,maxv = 0.0;
849f3ef73ceSBarry Smith   PetscViewerFormat format;
850f1af5d2fSBarry Smith 
851f1af5d2fSBarry Smith   PetscFunctionBegin;
852f1af5d2fSBarry Smith 
853f1af5d2fSBarry Smith   ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr);
854b0a32e0cSBarry Smith   ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr);
855b0a32e0cSBarry Smith   ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr);
856f1af5d2fSBarry Smith 
857f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
858fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
859f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
860b0a32e0cSBarry Smith     color = PETSC_DRAW_BLUE;
861f1af5d2fSBarry Smith     for(j = 0; j < n; j++) {
862f1af5d2fSBarry Smith       x_l = j;
863f1af5d2fSBarry Smith       x_r = x_l + 1.0;
864f1af5d2fSBarry Smith       for(i = 0; i < m; i++) {
865f1af5d2fSBarry Smith         y_l = m - i - 1.0;
866f1af5d2fSBarry Smith         y_r = y_l + 1.0;
867f1af5d2fSBarry Smith #if defined(PETSC_USE_COMPLEX)
868329f5518SBarry Smith         if (PetscRealPart(v[j*m+i]) >  0.) {
869b0a32e0cSBarry Smith           color = PETSC_DRAW_RED;
870329f5518SBarry Smith         } else if (PetscRealPart(v[j*m+i]) <  0.) {
871b0a32e0cSBarry Smith           color = PETSC_DRAW_BLUE;
872f1af5d2fSBarry Smith         } else {
873f1af5d2fSBarry Smith           continue;
874f1af5d2fSBarry Smith         }
875f1af5d2fSBarry Smith #else
876f1af5d2fSBarry Smith         if (v[j*m+i] >  0.) {
877b0a32e0cSBarry Smith           color = PETSC_DRAW_RED;
878f1af5d2fSBarry Smith         } else if (v[j*m+i] <  0.) {
879b0a32e0cSBarry Smith           color = PETSC_DRAW_BLUE;
880f1af5d2fSBarry Smith         } else {
881f1af5d2fSBarry Smith           continue;
882f1af5d2fSBarry Smith         }
883f1af5d2fSBarry Smith #endif
884b0a32e0cSBarry Smith         ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
885f1af5d2fSBarry Smith       }
886f1af5d2fSBarry Smith     }
887f1af5d2fSBarry Smith   } else {
888f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
889f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
890f1af5d2fSBarry Smith     for(i = 0; i < m*n; i++) {
891f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
892f1af5d2fSBarry Smith     }
893b0a32e0cSBarry Smith     scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv;
894b0a32e0cSBarry Smith     ierr  = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr);
895b0a32e0cSBarry Smith     if (popup) {ierr  = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);}
896f1af5d2fSBarry Smith     for(j = 0; j < n; j++) {
897f1af5d2fSBarry Smith       x_l = j;
898f1af5d2fSBarry Smith       x_r = x_l + 1.0;
899f1af5d2fSBarry Smith       for(i = 0; i < m; i++) {
900f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
901f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
902b0a32e0cSBarry Smith         color = PETSC_DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(v[j*m+i]));
903b0a32e0cSBarry Smith         ierr  = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr);
904f1af5d2fSBarry Smith       }
905f1af5d2fSBarry Smith     }
906f1af5d2fSBarry Smith   }
907f1af5d2fSBarry Smith   PetscFunctionReturn(0);
908f1af5d2fSBarry Smith }
909f1af5d2fSBarry Smith 
9104a2ae208SSatish Balay #undef __FUNCT__
9114a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqDense_Draw"
912b0a32e0cSBarry Smith int MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
913f1af5d2fSBarry Smith {
914b0a32e0cSBarry Smith   PetscDraw  draw;
915f1af5d2fSBarry Smith   PetscTruth isnull;
916329f5518SBarry Smith   PetscReal  xr,yr,xl,yl,h,w;
917f1af5d2fSBarry Smith   int        ierr;
918f1af5d2fSBarry Smith 
919f1af5d2fSBarry Smith   PetscFunctionBegin;
920b0a32e0cSBarry Smith   ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
921b0a32e0cSBarry Smith   ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr);
922f1af5d2fSBarry Smith   if (isnull == PETSC_TRUE) PetscFunctionReturn(0);
923f1af5d2fSBarry Smith 
924f1af5d2fSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr);
925273d9f13SBarry Smith   xr  = A->n; yr = A->m; h = yr/10.0; w = xr/10.0;
926f1af5d2fSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
927b0a32e0cSBarry Smith   ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr);
928b0a32e0cSBarry Smith   ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr);
929f1af5d2fSBarry Smith   ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr);
930f1af5d2fSBarry Smith   PetscFunctionReturn(0);
931f1af5d2fSBarry Smith }
932f1af5d2fSBarry Smith 
9334a2ae208SSatish Balay #undef __FUNCT__
9344a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqDense"
935b0a32e0cSBarry Smith int MatView_SeqDense(Mat A,PetscViewer viewer)
936932b0c3eSLois Curfman McInnes {
937932b0c3eSLois Curfman McInnes   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
938bcd2baecSBarry Smith   int          ierr;
939f1af5d2fSBarry Smith   PetscTruth   issocket,isascii,isbinary,isdraw;
940932b0c3eSLois Curfman McInnes 
9413a40ed3dSBarry Smith   PetscFunctionBegin;
942b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr);
943b0a32e0cSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
944fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
945fb9695e5SSatish Balay   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr);
9460f5bd95cSBarry Smith 
9470f5bd95cSBarry Smith   if (issocket) {
948b0a32e0cSBarry Smith     ierr = PetscViewerSocketPutScalar(viewer,A->m,A->n,a->v);CHKERRQ(ierr);
9490f5bd95cSBarry Smith   } else if (isascii) {
9503a40ed3dSBarry Smith     ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr);
9510f5bd95cSBarry Smith   } else if (isbinary) {
9523a40ed3dSBarry Smith     ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr);
953f1af5d2fSBarry Smith   } else if (isdraw) {
954f1af5d2fSBarry Smith     ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr);
9555cd90555SBarry Smith   } else {
95629bbc08cSBarry Smith     SETERRQ1(1,"Viewer type %s not supported by dense matrix",((PetscObject)viewer)->type_name);
957932b0c3eSLois Curfman McInnes   }
9583a40ed3dSBarry Smith   PetscFunctionReturn(0);
959932b0c3eSLois Curfman McInnes }
960289bc588SBarry Smith 
9614a2ae208SSatish Balay #undef __FUNCT__
9624a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqDense"
963c6e7dd08SBarry Smith int MatDestroy_SeqDense(Mat mat)
964289bc588SBarry Smith {
965ec8511deSBarry Smith   Mat_SeqDense *l = (Mat_SeqDense*)mat->data;
96690f02eecSBarry Smith   int          ierr;
96790f02eecSBarry Smith 
9683a40ed3dSBarry Smith   PetscFunctionBegin;
969aa482453SBarry Smith #if defined(PETSC_USE_LOG)
970b0a32e0cSBarry Smith   PetscLogObjectState((PetscObject)mat,"Rows %d Cols %d",mat->m,mat->n);
971a5a9c739SBarry Smith #endif
972606d414cSSatish Balay   if (l->pivots) {ierr = PetscFree(l->pivots);CHKERRQ(ierr);}
973606d414cSSatish Balay   if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);}
974606d414cSSatish Balay   ierr = PetscFree(l);CHKERRQ(ierr);
9753a40ed3dSBarry Smith   PetscFunctionReturn(0);
976289bc588SBarry Smith }
977289bc588SBarry Smith 
9784a2ae208SSatish Balay #undef __FUNCT__
9794a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqDense"
9808f6be9afSLois Curfman McInnes int MatTranspose_SeqDense(Mat A,Mat *matout)
981289bc588SBarry Smith {
982c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
983549d3d68SSatish Balay   int          k,j,m,n,ierr;
98487828ca2SBarry Smith   PetscScalar  *v,tmp;
98548b35521SBarry Smith 
9863a40ed3dSBarry Smith   PetscFunctionBegin;
987273d9f13SBarry Smith   v = mat->v; m = A->m; n = A->n;
9887c922b88SBarry Smith   if (!matout) { /* in place transpose */
989d64ed03dSBarry Smith     if (m != n) { /* malloc temp to hold transpose */
99087828ca2SBarry Smith       PetscScalar *w;
99187828ca2SBarry Smith       ierr = PetscMalloc((m+1)*(n+1)*sizeof(PetscScalar),&w);CHKERRQ(ierr);
992d64ed03dSBarry Smith       for (j=0; j<m; j++) {
993d64ed03dSBarry Smith         for (k=0; k<n; k++) {
994d64ed03dSBarry Smith           w[k + j*n] = v[j + k*m];
995d64ed03dSBarry Smith         }
996d64ed03dSBarry Smith       }
99787828ca2SBarry Smith       ierr = PetscMemcpy(v,w,m*n*sizeof(PetscScalar));CHKERRQ(ierr);
998606d414cSSatish Balay       ierr = PetscFree(w);CHKERRQ(ierr);
999d64ed03dSBarry Smith     } else {
1000d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1001289bc588SBarry Smith         for (k=0; k<j; k++) {
1002d3e5ee88SLois Curfman McInnes           tmp = v[j + k*n];
1003d3e5ee88SLois Curfman McInnes           v[j + k*n] = v[k + j*n];
1004d3e5ee88SLois Curfman McInnes           v[k + j*n] = tmp;
1005289bc588SBarry Smith         }
1006289bc588SBarry Smith       }
1007d64ed03dSBarry Smith     }
10083a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1009d3e5ee88SLois Curfman McInnes     Mat          tmat;
1010ec8511deSBarry Smith     Mat_SeqDense *tmatd;
101187828ca2SBarry Smith     PetscScalar  *v2;
1012ea709b57SSatish Balay 
1013273d9f13SBarry Smith     ierr  = MatCreateSeqDense(A->comm,A->n,A->m,PETSC_NULL,&tmat);CHKERRQ(ierr);
1014ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
10150de55854SLois Curfman McInnes     v = mat->v; v2 = tmatd->v;
1016d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
10170de55854SLois Curfman McInnes       for (k=0; k<m; k++) v2[j + k*n] = v[k + j*m];
1018d3e5ee88SLois Curfman McInnes     }
10196d4a8577SBarry Smith     ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
10206d4a8577SBarry Smith     ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1021d3e5ee88SLois Curfman McInnes     *matout = tmat;
102248b35521SBarry Smith   }
10233a40ed3dSBarry Smith   PetscFunctionReturn(0);
1024289bc588SBarry Smith }
1025289bc588SBarry Smith 
10264a2ae208SSatish Balay #undef __FUNCT__
10274a2ae208SSatish Balay #define __FUNCT__ "MatEqual_SeqDense"
10288f6be9afSLois Curfman McInnes int MatEqual_SeqDense(Mat A1,Mat A2,PetscTruth *flg)
1029289bc588SBarry Smith {
1030c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat1 = (Mat_SeqDense*)A1->data;
1031c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat2 = (Mat_SeqDense*)A2->data;
1032273d9f13SBarry Smith   int          ierr,i;
103387828ca2SBarry Smith   PetscScalar  *v1 = mat1->v,*v2 = mat2->v;
1034273d9f13SBarry Smith   PetscTruth   flag;
10359ea5d5aeSSatish Balay 
10363a40ed3dSBarry Smith   PetscFunctionBegin;
1037273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)A2,MATSEQDENSE,&flag);CHKERRQ(ierr);
1038273d9f13SBarry Smith   if (!flag) SETERRQ(PETSC_ERR_SUP,"Matrices should be of type  MATSEQDENSE");
1039273d9f13SBarry Smith   if (A1->m != A2->m) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1040273d9f13SBarry Smith   if (A1->n != A2->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1041273d9f13SBarry Smith   for (i=0; i<A1->m*A1->n; i++) {
10423a40ed3dSBarry Smith     if (*v1 != *v2) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1043289bc588SBarry Smith     v1++; v2++;
1044289bc588SBarry Smith   }
104577c4ece6SBarry Smith   *flg = PETSC_TRUE;
10463a40ed3dSBarry Smith   PetscFunctionReturn(0);
1047289bc588SBarry Smith }
1048289bc588SBarry Smith 
10494a2ae208SSatish Balay #undef __FUNCT__
10504a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqDense"
10518f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqDense(Mat A,Vec v)
1052289bc588SBarry Smith {
1053c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
10547a97a34bSBarry Smith   int          ierr,i,n,len;
105587828ca2SBarry Smith   PetscScalar  *x,zero = 0.0;
105644cd7ae7SLois Curfman McInnes 
10573a40ed3dSBarry Smith   PetscFunctionBegin;
10587a97a34bSBarry Smith   ierr = VecSet(&zero,v);CHKERRQ(ierr);
10597a97a34bSBarry Smith   ierr = VecGetSize(v,&n);CHKERRQ(ierr);
1060600d6d0bSBarry Smith   ierr = VecGetArray(v,&x);CHKERRQ(ierr);
1061273d9f13SBarry Smith   len = PetscMin(A->m,A->n);
1062273d9f13SBarry Smith   if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
106344cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1064273d9f13SBarry Smith     x[i] = mat->v[i*A->m + i];
1065289bc588SBarry Smith   }
10667a97a34bSBarry Smith   ierr = VecRestoreArray(v,&x);CHKERRQ(ierr);
10673a40ed3dSBarry Smith   PetscFunctionReturn(0);
1068289bc588SBarry Smith }
1069289bc588SBarry Smith 
10704a2ae208SSatish Balay #undef __FUNCT__
10714a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqDense"
10728f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1073289bc588SBarry Smith {
1074c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
107587828ca2SBarry Smith   PetscScalar  *l,*r,x,*v;
1076273d9f13SBarry Smith   int          ierr,i,j,m = A->m,n = A->n;
107755659b69SBarry Smith 
10783a40ed3dSBarry Smith   PetscFunctionBegin;
107928988994SBarry Smith   if (ll) {
10807a97a34bSBarry Smith     ierr = VecGetSize(ll,&m);CHKERRQ(ierr);
1081600d6d0bSBarry Smith     ierr = VecGetArray(ll,&l);CHKERRQ(ierr);
1082273d9f13SBarry Smith     if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1083da3a660dSBarry Smith     for (i=0; i<m; i++) {
1084da3a660dSBarry Smith       x = l[i];
1085da3a660dSBarry Smith       v = mat->v + i;
1086da3a660dSBarry Smith       for (j=0; j<n; j++) { (*v) *= x; v+= m;}
1087da3a660dSBarry Smith     }
10887a97a34bSBarry Smith     ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr);
1089b0a32e0cSBarry Smith     PetscLogFlops(n*m);
1090da3a660dSBarry Smith   }
109128988994SBarry Smith   if (rr) {
10927a97a34bSBarry Smith     ierr = VecGetSize(rr,&n);CHKERRQ(ierr);
1093600d6d0bSBarry Smith     ierr = VecGetArray(rr,&r);CHKERRQ(ierr);
1094273d9f13SBarry Smith     if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1095da3a660dSBarry Smith     for (i=0; i<n; i++) {
1096da3a660dSBarry Smith       x = r[i];
1097da3a660dSBarry Smith       v = mat->v + i*m;
1098da3a660dSBarry Smith       for (j=0; j<m; j++) { (*v++) *= x;}
1099da3a660dSBarry Smith     }
11007a97a34bSBarry Smith     ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr);
1101b0a32e0cSBarry Smith     PetscLogFlops(n*m);
1102da3a660dSBarry Smith   }
11033a40ed3dSBarry Smith   PetscFunctionReturn(0);
1104289bc588SBarry Smith }
1105289bc588SBarry Smith 
11064a2ae208SSatish Balay #undef __FUNCT__
11074a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqDense"
1108329f5518SBarry Smith int MatNorm_SeqDense(Mat A,NormType type,PetscReal *norm)
1109289bc588SBarry Smith {
1110c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
111187828ca2SBarry Smith   PetscScalar  *v = mat->v;
1112329f5518SBarry Smith   PetscReal    sum = 0.0;
1113289bc588SBarry Smith   int          i,j;
111455659b69SBarry Smith 
11153a40ed3dSBarry Smith   PetscFunctionBegin;
1116289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1117273d9f13SBarry Smith     for (i=0; i<A->n*A->m; i++) {
1118aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1119329f5518SBarry Smith       sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1120289bc588SBarry Smith #else
1121289bc588SBarry Smith       sum += (*v)*(*v); v++;
1122289bc588SBarry Smith #endif
1123289bc588SBarry Smith     }
1124289bc588SBarry Smith     *norm = sqrt(sum);
1125b0a32e0cSBarry Smith     PetscLogFlops(2*A->n*A->m);
11263a40ed3dSBarry Smith   } else if (type == NORM_1) {
1127289bc588SBarry Smith     *norm = 0.0;
1128273d9f13SBarry Smith     for (j=0; j<A->n; j++) {
1129289bc588SBarry Smith       sum = 0.0;
1130273d9f13SBarry Smith       for (i=0; i<A->m; i++) {
113133a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1132289bc588SBarry Smith       }
1133289bc588SBarry Smith       if (sum > *norm) *norm = sum;
1134289bc588SBarry Smith     }
1135b0a32e0cSBarry Smith     PetscLogFlops(A->n*A->m);
11363a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1137289bc588SBarry Smith     *norm = 0.0;
1138273d9f13SBarry Smith     for (j=0; j<A->m; j++) {
1139289bc588SBarry Smith       v = mat->v + j;
1140289bc588SBarry Smith       sum = 0.0;
1141273d9f13SBarry Smith       for (i=0; i<A->n; i++) {
1142273d9f13SBarry Smith         sum += PetscAbsScalar(*v); v += A->m;
1143289bc588SBarry Smith       }
1144289bc588SBarry Smith       if (sum > *norm) *norm = sum;
1145289bc588SBarry Smith     }
1146b0a32e0cSBarry Smith     PetscLogFlops(A->n*A->m);
11473a40ed3dSBarry Smith   } else {
114829bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"No two norm");
1149289bc588SBarry Smith   }
11503a40ed3dSBarry Smith   PetscFunctionReturn(0);
1151289bc588SBarry Smith }
1152289bc588SBarry Smith 
11534a2ae208SSatish Balay #undef __FUNCT__
11544a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqDense"
11558f6be9afSLois Curfman McInnes int MatSetOption_SeqDense(Mat A,MatOption op)
1156289bc588SBarry Smith {
1157c0bbcb79SLois Curfman McInnes   Mat_SeqDense *aij = (Mat_SeqDense*)A->data;
115867e560aaSBarry Smith 
11593a40ed3dSBarry Smith   PetscFunctionBegin;
1160b5a2b587SKris Buschelman   switch (op) {
1161b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
1162b5a2b587SKris Buschelman     aij->roworiented = PETSC_TRUE;
1163b5a2b587SKris Buschelman     break;
1164b5a2b587SKris Buschelman   case MAT_COLUMN_ORIENTED:
1165b5a2b587SKris Buschelman     aij->roworiented = PETSC_FALSE;
1166b5a2b587SKris Buschelman     break;
1167b5a2b587SKris Buschelman   case MAT_ROWS_SORTED:
1168b5a2b587SKris Buschelman   case MAT_ROWS_UNSORTED:
1169b5a2b587SKris Buschelman   case MAT_COLUMNS_SORTED:
1170b5a2b587SKris Buschelman   case MAT_COLUMNS_UNSORTED:
1171b5a2b587SKris Buschelman   case MAT_NO_NEW_NONZERO_LOCATIONS:
1172b5a2b587SKris Buschelman   case MAT_YES_NEW_NONZERO_LOCATIONS:
1173b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
1174b5a2b587SKris Buschelman   case MAT_NO_NEW_DIAGONALS:
1175b5a2b587SKris Buschelman   case MAT_YES_NEW_DIAGONALS:
1176b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1177b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
1178d03495bdSKris Buschelman   case MAT_USE_SINGLE_PRECISION_SOLVES:
1179b0a32e0cSBarry Smith     PetscLogInfo(A,"MatSetOption_SeqDense:Option ignored\n");
1180b5a2b587SKris Buschelman     break;
1181b5a2b587SKris Buschelman   default:
118229bbc08cSBarry Smith     SETERRQ(PETSC_ERR_SUP,"unknown option");
11833a40ed3dSBarry Smith   }
11843a40ed3dSBarry Smith   PetscFunctionReturn(0);
1185289bc588SBarry Smith }
1186289bc588SBarry Smith 
11874a2ae208SSatish Balay #undef __FUNCT__
11884a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqDense"
11898f6be9afSLois Curfman McInnes int MatZeroEntries_SeqDense(Mat A)
11906f0a148fSBarry Smith {
1191ec8511deSBarry Smith   Mat_SeqDense *l = (Mat_SeqDense*)A->data;
1192549d3d68SSatish Balay   int          ierr;
11933a40ed3dSBarry Smith 
11943a40ed3dSBarry Smith   PetscFunctionBegin;
119587828ca2SBarry Smith   ierr = PetscMemzero(l->v,A->m*A->n*sizeof(PetscScalar));CHKERRQ(ierr);
11963a40ed3dSBarry Smith   PetscFunctionReturn(0);
11976f0a148fSBarry Smith }
11986f0a148fSBarry Smith 
11994a2ae208SSatish Balay #undef __FUNCT__
12004a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqDense"
12018f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqDense(Mat A,int *bs)
12024e220ebcSLois Curfman McInnes {
12033a40ed3dSBarry Smith   PetscFunctionBegin;
12044e220ebcSLois Curfman McInnes   *bs = 1;
12053a40ed3dSBarry Smith   PetscFunctionReturn(0);
12064e220ebcSLois Curfman McInnes }
12074e220ebcSLois Curfman McInnes 
12084a2ae208SSatish Balay #undef __FUNCT__
12094a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqDense"
121087828ca2SBarry Smith int MatZeroRows_SeqDense(Mat A,IS is,PetscScalar *diag)
12116f0a148fSBarry Smith {
1212ec8511deSBarry Smith   Mat_SeqDense *l = (Mat_SeqDense*)A->data;
1213273d9f13SBarry Smith   int          n = A->n,i,j,ierr,N,*rows;
121487828ca2SBarry Smith   PetscScalar  *slot;
121555659b69SBarry Smith 
12163a40ed3dSBarry Smith   PetscFunctionBegin;
1217e03a110bSBarry Smith   ierr = ISGetLocalSize(is,&N);CHKERRQ(ierr);
121878b31e54SBarry Smith   ierr = ISGetIndices(is,&rows);CHKERRQ(ierr);
12196f0a148fSBarry Smith   for (i=0; i<N; i++) {
12206f0a148fSBarry Smith     slot = l->v + rows[i];
12216f0a148fSBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += n;}
12226f0a148fSBarry Smith   }
12236f0a148fSBarry Smith   if (diag) {
12246f0a148fSBarry Smith     for (i=0; i<N; i++) {
12256f0a148fSBarry Smith       slot = l->v + (n+1)*rows[i];
1226260925b8SBarry Smith       *slot = *diag;
12276f0a148fSBarry Smith     }
12286f0a148fSBarry Smith   }
1229260925b8SBarry Smith   ISRestoreIndices(is,&rows);
12303a40ed3dSBarry Smith   PetscFunctionReturn(0);
12316f0a148fSBarry Smith }
1232557bce09SLois Curfman McInnes 
12334a2ae208SSatish Balay #undef __FUNCT__
12344a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqDense"
123587828ca2SBarry Smith int MatGetArray_SeqDense(Mat A,PetscScalar **array)
123664e87e97SBarry Smith {
1237c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
12383a40ed3dSBarry Smith 
12393a40ed3dSBarry Smith   PetscFunctionBegin;
124064e87e97SBarry Smith   *array = mat->v;
12413a40ed3dSBarry Smith   PetscFunctionReturn(0);
124264e87e97SBarry Smith }
12430754003eSLois Curfman McInnes 
12444a2ae208SSatish Balay #undef __FUNCT__
12454a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqDense"
124687828ca2SBarry Smith int MatRestoreArray_SeqDense(Mat A,PetscScalar **array)
1247ff14e315SSatish Balay {
12483a40ed3dSBarry Smith   PetscFunctionBegin;
124909b544d4SBarry Smith   *array = 0; /* user cannot accidently use the array later */
12503a40ed3dSBarry Smith   PetscFunctionReturn(0);
1251ff14e315SSatish Balay }
12520754003eSLois Curfman McInnes 
12534a2ae208SSatish Balay #undef __FUNCT__
12544a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqDense"
12557b2a1423SBarry Smith static int MatGetSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,int cs,MatReuse scall,Mat *B)
12560754003eSLois Curfman McInnes {
1257c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
1258273d9f13SBarry Smith   int          i,j,ierr,m = A->m,*irow,*icol,nrows,ncols;
125987828ca2SBarry Smith   PetscScalar  *av,*bv,*v = mat->v;
12600754003eSLois Curfman McInnes   Mat          newmat;
12610754003eSLois Curfman McInnes 
12623a40ed3dSBarry Smith   PetscFunctionBegin;
126378b31e54SBarry Smith   ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr);
126478b31e54SBarry Smith   ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr);
1265e03a110bSBarry Smith   ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr);
1266e03a110bSBarry Smith   ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr);
12670754003eSLois Curfman McInnes 
1268182d2002SSatish Balay   /* Check submatrixcall */
1269182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
1270182d2002SSatish Balay     int n_cols,n_rows;
1271182d2002SSatish Balay     ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr);
127229bbc08cSBarry Smith     if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size");
1273182d2002SSatish Balay     newmat = *B;
1274182d2002SSatish Balay   } else {
12750754003eSLois Curfman McInnes     /* Create and fill new matrix */
1276b4fd4287SBarry Smith     ierr = MatCreateSeqDense(A->comm,nrows,ncols,PETSC_NULL,&newmat);CHKERRQ(ierr);
1277182d2002SSatish Balay   }
1278182d2002SSatish Balay 
1279182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
1280182d2002SSatish Balay   bv = ((Mat_SeqDense*)newmat->data)->v;
1281182d2002SSatish Balay 
1282182d2002SSatish Balay   for (i=0; i<ncols; i++) {
1283182d2002SSatish Balay     av = v + m*icol[i];
1284182d2002SSatish Balay     for (j=0; j<nrows; j++) {
1285182d2002SSatish Balay       *bv++ = av[irow[j]];
12860754003eSLois Curfman McInnes     }
12870754003eSLois Curfman McInnes   }
1288182d2002SSatish Balay 
1289182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
12906d4a8577SBarry Smith   ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
12916d4a8577SBarry Smith   ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
12920754003eSLois Curfman McInnes 
12930754003eSLois Curfman McInnes   /* Free work space */
129478b31e54SBarry Smith   ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr);
129578b31e54SBarry Smith   ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr);
1296182d2002SSatish Balay   *B = newmat;
12973a40ed3dSBarry Smith   PetscFunctionReturn(0);
12980754003eSLois Curfman McInnes }
12990754003eSLois Curfman McInnes 
13004a2ae208SSatish Balay #undef __FUNCT__
13014a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqDense"
13027b2a1423SBarry Smith int MatGetSubMatrices_SeqDense(Mat A,int n,IS *irow,IS *icol,MatReuse scall,Mat **B)
1303905e6a2fSBarry Smith {
1304905e6a2fSBarry Smith   int ierr,i;
1305905e6a2fSBarry Smith 
13063a40ed3dSBarry Smith   PetscFunctionBegin;
1307905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
1308b0a32e0cSBarry Smith     ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr);
1309905e6a2fSBarry Smith   }
1310905e6a2fSBarry Smith 
1311905e6a2fSBarry Smith   for (i=0; i<n; i++) {
13126a6a5d1dSBarry Smith     ierr = MatGetSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr);
1313905e6a2fSBarry Smith   }
13143a40ed3dSBarry Smith   PetscFunctionReturn(0);
1315905e6a2fSBarry Smith }
1316905e6a2fSBarry Smith 
13174a2ae208SSatish Balay #undef __FUNCT__
13184a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqDense"
1319cb5b572fSBarry Smith int MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
13204b0e389bSBarry Smith {
13214b0e389bSBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense *)B->data;
13223a40ed3dSBarry Smith   int          ierr;
1323273d9f13SBarry Smith   PetscTruth   flag;
13243a40ed3dSBarry Smith 
13253a40ed3dSBarry Smith   PetscFunctionBegin;
1326273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQDENSE,&flag);CHKERRQ(ierr);
1327273d9f13SBarry Smith   if (!flag) {
1328cb5b572fSBarry Smith     ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr);
13293a40ed3dSBarry Smith     PetscFunctionReturn(0);
13303a40ed3dSBarry Smith   }
1331273d9f13SBarry Smith   if (A->m != B->m || A->n != B->n) SETERRQ(PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
133287828ca2SBarry Smith   ierr = PetscMemcpy(b->v,a->v,A->m*A->n*sizeof(PetscScalar));CHKERRQ(ierr);
1333273d9f13SBarry Smith   PetscFunctionReturn(0);
1334273d9f13SBarry Smith }
1335273d9f13SBarry Smith 
13364a2ae208SSatish Balay #undef __FUNCT__
13374a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqDense"
1338273d9f13SBarry Smith int MatSetUpPreallocation_SeqDense(Mat A)
1339273d9f13SBarry Smith {
1340273d9f13SBarry Smith   int        ierr;
1341273d9f13SBarry Smith 
1342273d9f13SBarry Smith   PetscFunctionBegin;
1343273d9f13SBarry Smith   ierr =  MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr);
13443a40ed3dSBarry Smith   PetscFunctionReturn(0);
13454b0e389bSBarry Smith }
13464b0e389bSBarry Smith 
1347289bc588SBarry Smith /* -------------------------------------------------------------------*/
1348a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense,
1349905e6a2fSBarry Smith        MatGetRow_SeqDense,
1350905e6a2fSBarry Smith        MatRestoreRow_SeqDense,
1351905e6a2fSBarry Smith        MatMult_SeqDense,
1352905e6a2fSBarry Smith        MatMultAdd_SeqDense,
13537c922b88SBarry Smith        MatMultTranspose_SeqDense,
13547c922b88SBarry Smith        MatMultTransposeAdd_SeqDense,
1355905e6a2fSBarry Smith        MatSolve_SeqDense,
1356905e6a2fSBarry Smith        MatSolveAdd_SeqDense,
13577c922b88SBarry Smith        MatSolveTranspose_SeqDense,
13587c922b88SBarry Smith        MatSolveTransposeAdd_SeqDense,
1359905e6a2fSBarry Smith        MatLUFactor_SeqDense,
1360905e6a2fSBarry Smith        MatCholeskyFactor_SeqDense,
1361ec8511deSBarry Smith        MatRelax_SeqDense,
1362ec8511deSBarry Smith        MatTranspose_SeqDense,
1363905e6a2fSBarry Smith        MatGetInfo_SeqDense,
1364905e6a2fSBarry Smith        MatEqual_SeqDense,
1365905e6a2fSBarry Smith        MatGetDiagonal_SeqDense,
1366905e6a2fSBarry Smith        MatDiagonalScale_SeqDense,
1367905e6a2fSBarry Smith        MatNorm_SeqDense,
1368905e6a2fSBarry Smith        0,
1369905e6a2fSBarry Smith        0,
1370905e6a2fSBarry Smith        0,
1371905e6a2fSBarry Smith        MatSetOption_SeqDense,
1372905e6a2fSBarry Smith        MatZeroEntries_SeqDense,
1373905e6a2fSBarry Smith        MatZeroRows_SeqDense,
1374905e6a2fSBarry Smith        MatLUFactorSymbolic_SeqDense,
1375905e6a2fSBarry Smith        MatLUFactorNumeric_SeqDense,
1376905e6a2fSBarry Smith        MatCholeskyFactorSymbolic_SeqDense,
1377905e6a2fSBarry Smith        MatCholeskyFactorNumeric_SeqDense,
1378273d9f13SBarry Smith        MatSetUpPreallocation_SeqDense,
1379273d9f13SBarry Smith        0,
1380905e6a2fSBarry Smith        0,
1381905e6a2fSBarry Smith        MatGetArray_SeqDense,
1382905e6a2fSBarry Smith        MatRestoreArray_SeqDense,
13835609ef8eSBarry Smith        MatDuplicate_SeqDense,
1384a5ae1ecdSBarry Smith        0,
1385a5ae1ecdSBarry Smith        0,
1386a5ae1ecdSBarry Smith        0,
1387a5ae1ecdSBarry Smith        0,
1388a5ae1ecdSBarry Smith        MatAXPY_SeqDense,
1389a5ae1ecdSBarry Smith        MatGetSubMatrices_SeqDense,
1390a5ae1ecdSBarry Smith        0,
13914b0e389bSBarry Smith        MatGetValues_SeqDense,
1392a5ae1ecdSBarry Smith        MatCopy_SeqDense,
1393a5ae1ecdSBarry Smith        0,
1394a5ae1ecdSBarry Smith        MatScale_SeqDense,
1395a5ae1ecdSBarry Smith        0,
1396a5ae1ecdSBarry Smith        0,
1397a5ae1ecdSBarry Smith        0,
1398a5ae1ecdSBarry Smith        MatGetBlockSize_SeqDense,
1399a5ae1ecdSBarry Smith        0,
1400a5ae1ecdSBarry Smith        0,
1401a5ae1ecdSBarry Smith        0,
1402a5ae1ecdSBarry Smith        0,
1403a5ae1ecdSBarry Smith        0,
1404a5ae1ecdSBarry Smith        0,
1405a5ae1ecdSBarry Smith        0,
1406a5ae1ecdSBarry Smith        0,
1407a5ae1ecdSBarry Smith        0,
1408a5ae1ecdSBarry Smith        0,
1409e03a110bSBarry Smith        MatDestroy_SeqDense,
1410e03a110bSBarry Smith        MatView_SeqDense,
14118a124369SBarry Smith        MatGetPetscMaps_Petsc};
141290ace30eSBarry Smith 
14134a2ae208SSatish Balay #undef __FUNCT__
14144a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqDense"
14154b828684SBarry Smith /*@C
1416fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
1417d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
1418d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
1419289bc588SBarry Smith 
1420db81eaa0SLois Curfman McInnes    Collective on MPI_Comm
1421db81eaa0SLois Curfman McInnes 
142220563c6bSBarry Smith    Input Parameters:
1423db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
14240c775827SLois Curfman McInnes .  m - number of rows
142518f449edSLois Curfman McInnes .  n - number of columns
1426db81eaa0SLois Curfman McInnes -  data - optional location of matrix data.  Set data=PETSC_NULL for PETSc
1427dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
142820563c6bSBarry Smith 
142920563c6bSBarry Smith    Output Parameter:
143044cd7ae7SLois Curfman McInnes .  A - the matrix
143120563c6bSBarry Smith 
1432b259b22eSLois Curfman McInnes    Notes:
143318f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
143418f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
1435b4fd4287SBarry Smith    set data=PETSC_NULL.
143618f449edSLois Curfman McInnes 
1437027ccd11SLois Curfman McInnes    Level: intermediate
1438027ccd11SLois Curfman McInnes 
1439dbd7a890SLois Curfman McInnes .keywords: dense, matrix, LAPACK, BLAS
1440d65003e9SLois Curfman McInnes 
1441db81eaa0SLois Curfman McInnes .seealso: MatCreate(), MatCreateMPIDense(), MatSetValues()
144220563c6bSBarry Smith @*/
144387828ca2SBarry Smith int MatCreateSeqDense(MPI_Comm comm,int m,int n,PetscScalar *data,Mat *A)
1444289bc588SBarry Smith {
1445273d9f13SBarry Smith   int ierr;
14463b2fbd54SBarry Smith 
14473a40ed3dSBarry Smith   PetscFunctionBegin;
1448273d9f13SBarry Smith   ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr);
1449273d9f13SBarry Smith   ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr);
1450273d9f13SBarry Smith   ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr);
1451273d9f13SBarry Smith   PetscFunctionReturn(0);
1452273d9f13SBarry Smith }
1453273d9f13SBarry Smith 
14544a2ae208SSatish Balay #undef __FUNCT__
14554a2ae208SSatish Balay #define __FUNCT__ "MatSeqDensePreallocation"
1456273d9f13SBarry Smith /*@C
1457273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
1458273d9f13SBarry Smith 
1459273d9f13SBarry Smith    Collective on MPI_Comm
1460273d9f13SBarry Smith 
1461273d9f13SBarry Smith    Input Parameters:
1462273d9f13SBarry Smith +  A - the matrix
1463273d9f13SBarry Smith -  data - the array (or PETSC_NULL)
1464273d9f13SBarry Smith 
1465273d9f13SBarry Smith    Notes:
1466273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
1467273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
1468273d9f13SBarry Smith    set data=PETSC_NULL.
1469273d9f13SBarry Smith 
1470273d9f13SBarry Smith    Level: intermediate
1471273d9f13SBarry Smith 
1472273d9f13SBarry Smith .keywords: dense, matrix, LAPACK, BLAS
1473273d9f13SBarry Smith 
1474273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIDense(), MatSetValues()
1475273d9f13SBarry Smith @*/
147687828ca2SBarry Smith int MatSeqDenseSetPreallocation(Mat B,PetscScalar *data)
1477273d9f13SBarry Smith {
1478273d9f13SBarry Smith   Mat_SeqDense *b;
1479273d9f13SBarry Smith   int          ierr;
1480273d9f13SBarry Smith   PetscTruth   flg2;
1481273d9f13SBarry Smith 
1482273d9f13SBarry Smith   PetscFunctionBegin;
1483273d9f13SBarry Smith   ierr = PetscTypeCompare((PetscObject)B,MATSEQDENSE,&flg2);CHKERRQ(ierr);
1484273d9f13SBarry Smith   if (!flg2) PetscFunctionReturn(0);
1485273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
1486273d9f13SBarry Smith   b               = (Mat_SeqDense*)B->data;
1487273d9f13SBarry Smith   if (!data) {
148887828ca2SBarry Smith     ierr          = PetscMalloc((B->m*B->n+1)*sizeof(PetscScalar),&b->v);CHKERRQ(ierr);
148987828ca2SBarry Smith     ierr          = PetscMemzero(b->v,B->m*B->n*sizeof(PetscScalar));CHKERRQ(ierr);
1490273d9f13SBarry Smith     b->user_alloc = PETSC_FALSE;
149187828ca2SBarry Smith     PetscLogObjectMemory(B,B->n*B->m*sizeof(PetscScalar));
1492273d9f13SBarry Smith   } else { /* user-allocated storage */
1493273d9f13SBarry Smith     b->v          = data;
1494273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
1495273d9f13SBarry Smith   }
1496273d9f13SBarry Smith   PetscFunctionReturn(0);
1497273d9f13SBarry Smith }
1498273d9f13SBarry Smith 
1499273d9f13SBarry Smith EXTERN_C_BEGIN
15004a2ae208SSatish Balay #undef __FUNCT__
15014a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqDense"
1502273d9f13SBarry Smith int MatCreate_SeqDense(Mat B)
1503273d9f13SBarry Smith {
1504273d9f13SBarry Smith   Mat_SeqDense *b;
1505273d9f13SBarry Smith   int          ierr,size;
1506273d9f13SBarry Smith 
1507273d9f13SBarry Smith   PetscFunctionBegin;
1508273d9f13SBarry Smith   ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr);
150929bbc08cSBarry Smith   if (size > 1) SETERRQ(PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
151055659b69SBarry Smith 
1511273d9f13SBarry Smith   B->m = B->M = PetscMax(B->m,B->M);
1512273d9f13SBarry Smith   B->n = B->N = PetscMax(B->n,B->N);
1513273d9f13SBarry Smith 
1514b0a32e0cSBarry Smith   ierr            = PetscNew(Mat_SeqDense,&b);CHKERRQ(ierr);
1515549d3d68SSatish Balay   ierr            = PetscMemzero(b,sizeof(Mat_SeqDense));CHKERRQ(ierr);
1516549d3d68SSatish Balay   ierr            = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
151744cd7ae7SLois Curfman McInnes   B->factor       = 0;
151890f02eecSBarry Smith   B->mapping      = 0;
1519b0a32e0cSBarry Smith   PetscLogObjectMemory(B,sizeof(struct _p_Mat));
152044cd7ae7SLois Curfman McInnes   B->data         = (void*)b;
152118f449edSLois Curfman McInnes 
15228a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr);
15238a124369SBarry Smith   ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr);
1524a5ae1ecdSBarry Smith 
152544cd7ae7SLois Curfman McInnes   b->pivots       = 0;
1526273d9f13SBarry Smith   b->roworiented  = PETSC_TRUE;
1527273d9f13SBarry Smith   b->v            = 0;
15284e220ebcSLois Curfman McInnes 
15293a40ed3dSBarry Smith   PetscFunctionReturn(0);
1530289bc588SBarry Smith }
1531273d9f13SBarry Smith EXTERN_C_END
15323b2fbd54SBarry Smith 
15333b2fbd54SBarry Smith 
15343b2fbd54SBarry Smith 
15353b2fbd54SBarry Smith 
1536