xref: /petsc/src/mat/impls/adj/mpi/mpiadj.c (revision b97cf49b8d97305ad9adb42ff93e7a781049f527)
1*b97cf49bSBarry Smith #ifdef PETSC_RCS_HEADER
2*b97cf49bSBarry Smith static char vcid[] = "$Id: adj.c,v 1.5 1997/08/22 15:14:50 bsmith Exp $";
3*b97cf49bSBarry Smith #endif
4*b97cf49bSBarry Smith 
5*b97cf49bSBarry Smith /*
6*b97cf49bSBarry Smith     Defines the basic matrix operations for the ADJ adjacency list matrix data-structure.
7*b97cf49bSBarry Smith */
8*b97cf49bSBarry Smith 
9*b97cf49bSBarry Smith #include "pinclude/pviewer.h"
10*b97cf49bSBarry Smith #include "sys.h"
11*b97cf49bSBarry Smith #include "src/mat/impls/adj/seq/adj.h"
12*b97cf49bSBarry Smith #include "src/inline/bitarray.h"
13*b97cf49bSBarry Smith 
14*b97cf49bSBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**);
15*b97cf49bSBarry Smith 
16*b97cf49bSBarry Smith #undef __FUNC__
17*b97cf49bSBarry Smith #define __FUNC__ "MatGetRowIJ_SeqAdj"
18*b97cf49bSBarry Smith int MatGetRowIJ_SeqAdj(Mat A,int oshift,PetscTruth symmetric,int *m,int **ia,int **ja,
19*b97cf49bSBarry Smith                            PetscTruth *done)
20*b97cf49bSBarry Smith {
21*b97cf49bSBarry Smith   Mat_SeqAdj *a = (Mat_SeqAdj *) A->data;
22*b97cf49bSBarry Smith   int        ierr,i;
23*b97cf49bSBarry Smith 
24*b97cf49bSBarry Smith   *m     = A->m;
25*b97cf49bSBarry Smith   if (!ia) return 0;
26*b97cf49bSBarry Smith   if (symmetric && !a->symmetric) {
27*b97cf49bSBarry Smith     ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,0,oshift,ia,ja); CHKERRQ(ierr);
28*b97cf49bSBarry Smith   } else if (oshift == 1) {
29*b97cf49bSBarry Smith     int nz = a->i[a->m] + 1;
30*b97cf49bSBarry Smith     /* malloc space and  add 1 to i and j indices */
31*b97cf49bSBarry Smith     *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) ); CHKPTRQ(*ia);
32*b97cf49bSBarry Smith     *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(*ja);
33*b97cf49bSBarry Smith     for ( i=0; i<nz; i++ )     (*ja)[i] = a->j[i] + 1;
34*b97cf49bSBarry Smith     for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] + 1;
35*b97cf49bSBarry Smith   } else {
36*b97cf49bSBarry Smith     *ia = a->i; *ja = a->j;
37*b97cf49bSBarry Smith   }
38*b97cf49bSBarry Smith 
39*b97cf49bSBarry Smith   return 0;
40*b97cf49bSBarry Smith }
41*b97cf49bSBarry Smith 
42*b97cf49bSBarry Smith #undef __FUNC__
43*b97cf49bSBarry Smith #define __FUNC__ "MatRestoreRowIJ_SeqAdj"
44*b97cf49bSBarry Smith int MatRestoreRowIJ_SeqAdj(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,
45*b97cf49bSBarry Smith                                PetscTruth *done)
46*b97cf49bSBarry Smith {
47*b97cf49bSBarry Smith   Mat_SeqAdj *a = (Mat_SeqAdj *) A->data;
48*b97cf49bSBarry Smith 
49*b97cf49bSBarry Smith   if (!ia) return 0;
50*b97cf49bSBarry Smith   if ((symmetric && !a->symmetric) || oshift == 1) {
51*b97cf49bSBarry Smith     PetscFree(*ia);
52*b97cf49bSBarry Smith     PetscFree(*ja);
53*b97cf49bSBarry Smith   }
54*b97cf49bSBarry Smith   return 0;
55*b97cf49bSBarry Smith }
56*b97cf49bSBarry Smith 
57*b97cf49bSBarry Smith #undef __FUNC__
58*b97cf49bSBarry Smith #define __FUNC__ "MatView_SeqAdj_Binary"
59*b97cf49bSBarry Smith extern int MatView_SeqAdj_Binary(Mat A,Viewer viewer)
60*b97cf49bSBarry Smith {
61*b97cf49bSBarry Smith   Mat_SeqAdj *a = (Mat_SeqAdj *) A->data;
62*b97cf49bSBarry Smith   int        i, fd, *col_lens, ierr;
63*b97cf49bSBarry Smith   Scalar     *values;
64*b97cf49bSBarry Smith 
65*b97cf49bSBarry Smith   ierr        = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr);
66*b97cf49bSBarry Smith   col_lens    = (int *) PetscMalloc( (4+a->m)*sizeof(int) ); CHKPTRQ(col_lens);
67*b97cf49bSBarry Smith   col_lens[0] = MAT_COOKIE;
68*b97cf49bSBarry Smith   col_lens[1] = a->m;
69*b97cf49bSBarry Smith   col_lens[2] = a->n;
70*b97cf49bSBarry Smith   col_lens[3] = a->nz;
71*b97cf49bSBarry Smith 
72*b97cf49bSBarry Smith   /* store lengths of each row and write (including header) to file */
73*b97cf49bSBarry Smith   for ( i=0; i<a->m; i++ ) {
74*b97cf49bSBarry Smith     col_lens[4+i] = a->i[i+1] - a->i[i];
75*b97cf49bSBarry Smith   }
76*b97cf49bSBarry Smith   ierr = PetscBinaryWrite(fd,col_lens,4+a->m,BINARY_INT,1); CHKERRQ(ierr);
77*b97cf49bSBarry Smith   PetscFree(col_lens);
78*b97cf49bSBarry Smith 
79*b97cf49bSBarry Smith   /* store column indices (zero start index) */
80*b97cf49bSBarry Smith   ierr = PetscBinaryWrite(fd,a->j,a->nz,BINARY_INT,0); CHKERRQ(ierr);
81*b97cf49bSBarry Smith 
82*b97cf49bSBarry Smith   /* store nonzero values */
83*b97cf49bSBarry Smith   values = (Scalar *) PetscMalloc( a->nz*sizeof(Scalar) );CHKPTRQ(values);
84*b97cf49bSBarry Smith   PetscMemzero(values,a->nz*sizeof(Scalar) );
85*b97cf49bSBarry Smith   ierr = PetscBinaryWrite(fd,values,a->nz,BINARY_SCALAR,0); CHKERRQ(ierr);
86*b97cf49bSBarry Smith   PetscFree(values);
87*b97cf49bSBarry Smith   return 0;
88*b97cf49bSBarry Smith }
89*b97cf49bSBarry Smith 
90*b97cf49bSBarry Smith #undef __FUNC__
91*b97cf49bSBarry Smith #define __FUNC__ "MatView_SeqAdj_ASCII"
92*b97cf49bSBarry Smith extern int MatView_SeqAdj_ASCII(Mat A,Viewer viewer)
93*b97cf49bSBarry Smith {
94*b97cf49bSBarry Smith   Mat_SeqAdj  *a = (Mat_SeqAdj *) A->data;
95*b97cf49bSBarry Smith   int         ierr, i,j, m = a->m,  format;
96*b97cf49bSBarry Smith   FILE        *fd;
97*b97cf49bSBarry Smith   char        *outputname;
98*b97cf49bSBarry Smith 
99*b97cf49bSBarry Smith   ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr);
100*b97cf49bSBarry Smith   ierr = ViewerFileGetOutputname_Private(viewer,&outputname); CHKERRQ(ierr);
101*b97cf49bSBarry Smith   ierr = ViewerGetFormat(viewer,&format);
102*b97cf49bSBarry Smith   if (format == VIEWER_FORMAT_ASCII_INFO) {
103*b97cf49bSBarry Smith     return 0;
104*b97cf49bSBarry Smith   }
105*b97cf49bSBarry Smith   else if (format == VIEWER_FORMAT_ASCII_MATLAB) {
106*b97cf49bSBarry Smith     fprintf(fd,"%% Size = %d %d \n",m,a->n);
107*b97cf49bSBarry Smith     fprintf(fd,"%% Nonzeros = %d \n",a->nz);
108*b97cf49bSBarry Smith     fprintf(fd,"zzz = zeros(%d,3);\n",a->nz);
109*b97cf49bSBarry Smith     fprintf(fd,"zzz = [\n");
110*b97cf49bSBarry Smith 
111*b97cf49bSBarry Smith     for (i=0; i<m; i++) {
112*b97cf49bSBarry Smith       for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
113*b97cf49bSBarry Smith #if defined(PETSC_COMPLEX)
114*b97cf49bSBarry Smith         fprintf(fd,"%d %d  %18.16e + %18.16e i \n",i+1,a->j[j],0.0,0.0);
115*b97cf49bSBarry Smith #else
116*b97cf49bSBarry Smith         fprintf(fd,"%d %d  %18.16e\n", i+1, a->j[j], 0.0);
117*b97cf49bSBarry Smith #endif
118*b97cf49bSBarry Smith       }
119*b97cf49bSBarry Smith     }
120*b97cf49bSBarry Smith     fprintf(fd,"];\n %s = spconvert(zzz);\n",outputname);
121*b97cf49bSBarry Smith   }
122*b97cf49bSBarry Smith   else if (format == VIEWER_FORMAT_ASCII_COMMON) {
123*b97cf49bSBarry Smith     for ( i=0; i<m; i++ ) {
124*b97cf49bSBarry Smith       fprintf(fd,"row %d:",i);
125*b97cf49bSBarry Smith       for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
126*b97cf49bSBarry Smith #if defined(PETSC_COMPLEX)
127*b97cf49bSBarry Smith         fprintf(fd," %d %g + %g i",a->j[j],0.0,0.0);
128*b97cf49bSBarry Smith #else
129*b97cf49bSBarry Smith         fprintf(fd," %d %g ",a->j[j],0.0);
130*b97cf49bSBarry Smith #endif
131*b97cf49bSBarry Smith       }
132*b97cf49bSBarry Smith       fprintf(fd,"\n");
133*b97cf49bSBarry Smith     }
134*b97cf49bSBarry Smith   }
135*b97cf49bSBarry Smith   else {
136*b97cf49bSBarry Smith     for ( i=0; i<m; i++ ) {
137*b97cf49bSBarry Smith       fprintf(fd,"row %d:",i);
138*b97cf49bSBarry Smith       for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
139*b97cf49bSBarry Smith #if defined(PETSC_COMPLEX)
140*b97cf49bSBarry Smith         fprintf(fd," %d %g + %g i",a->j[j],0.0,0.0);
141*b97cf49bSBarry Smith #else
142*b97cf49bSBarry Smith         fprintf(fd," %d %g ",a->j[j],0.0);
143*b97cf49bSBarry Smith #endif
144*b97cf49bSBarry Smith       }
145*b97cf49bSBarry Smith       fprintf(fd,"\n");
146*b97cf49bSBarry Smith     }
147*b97cf49bSBarry Smith   }
148*b97cf49bSBarry Smith   fflush(fd);
149*b97cf49bSBarry Smith   return 0;
150*b97cf49bSBarry Smith }
151*b97cf49bSBarry Smith 
152*b97cf49bSBarry Smith #undef __FUNC__
153*b97cf49bSBarry Smith #define __FUNC__ "MatView_SeqAdj_Draw"
154*b97cf49bSBarry Smith extern int MatView_SeqAdj_Draw(Mat A,Viewer viewer)
155*b97cf49bSBarry Smith {
156*b97cf49bSBarry Smith   Mat_SeqAdj  *a = (Mat_SeqAdj *) A->data;
157*b97cf49bSBarry Smith   int         ierr, i,j, m = a->m,color;
158*b97cf49bSBarry Smith   int         format;
159*b97cf49bSBarry Smith   double      xl,yl,xr,yr,w,h,x_l,x_r,y_l,y_r;
160*b97cf49bSBarry Smith   Draw        draw;
161*b97cf49bSBarry Smith   PetscTruth  isnull;
162*b97cf49bSBarry Smith 
163*b97cf49bSBarry Smith   ierr = ViewerDrawGetDraw(viewer,&draw); CHKERRQ(ierr);
164*b97cf49bSBarry Smith   ierr = DrawCheckResizedWindow(draw); CHKERRQ(ierr);
165*b97cf49bSBarry Smith   ierr = DrawClear(draw); CHKERRQ(ierr);
166*b97cf49bSBarry Smith   ierr = ViewerGetFormat(viewer,&format); CHKERRQ(ierr);
167*b97cf49bSBarry Smith   ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); if (isnull) return 0;
168*b97cf49bSBarry Smith 
169*b97cf49bSBarry Smith   xr  = a->n; yr = a->m; h = yr/10.0; w = xr/10.0;
170*b97cf49bSBarry Smith   xr += w;    yr += h;  xl = -w;     yl = -h;
171*b97cf49bSBarry Smith   ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr);
172*b97cf49bSBarry Smith   /* loop over matrix elements drawing boxes */
173*b97cf49bSBarry Smith 
174*b97cf49bSBarry Smith   if (format != VIEWER_FORMAT_DRAW_CONTOUR) {
175*b97cf49bSBarry Smith     color = DRAW_BLUE;
176*b97cf49bSBarry Smith     for ( i=0; i<m; i++ ) {
177*b97cf49bSBarry Smith       y_l = m - i - 1.0; y_r = y_l + 1.0;
178*b97cf49bSBarry Smith       for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
179*b97cf49bSBarry Smith         x_l = a->j[j]; x_r = x_l + 1.0;
180*b97cf49bSBarry Smith         DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);
181*b97cf49bSBarry Smith       }
182*b97cf49bSBarry Smith     }
183*b97cf49bSBarry Smith   }
184*b97cf49bSBarry Smith   ierr = DrawPause(draw); CHKERRQ(ierr);
185*b97cf49bSBarry Smith   return 0;
186*b97cf49bSBarry Smith }
187*b97cf49bSBarry Smith 
188*b97cf49bSBarry Smith #undef __FUNC__
189*b97cf49bSBarry Smith #define __FUNC__ "MatView_SeqAdj"
190*b97cf49bSBarry Smith int MatView_SeqAdj(PetscObject obj,Viewer viewer)
191*b97cf49bSBarry Smith {
192*b97cf49bSBarry Smith   Mat         A = (Mat) obj;
193*b97cf49bSBarry Smith   Mat_SeqAdj  *a = (Mat_SeqAdj*) A->data;
194*b97cf49bSBarry Smith   ViewerType  vtype;
195*b97cf49bSBarry Smith   int         ierr;
196*b97cf49bSBarry Smith 
197*b97cf49bSBarry Smith   ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr);
198*b97cf49bSBarry Smith   if (vtype == MATLAB_VIEWER) {
199*b97cf49bSBarry Smith     Scalar *values;
200*b97cf49bSBarry Smith     values = (Scalar *) PetscMalloc(a->nz*sizeof(Scalar));CHKPTRQ(values);
201*b97cf49bSBarry Smith     PetscMemzero(values,a->nz*sizeof(Scalar));
202*b97cf49bSBarry Smith     ierr = ViewerMatlabPutSparse_Private(viewer,a->m,a->n,a->nz,values,a->i,a->j);CHKERRQ(ierr);
203*b97cf49bSBarry Smith     PetscFree(values);
204*b97cf49bSBarry Smith   }
205*b97cf49bSBarry Smith   else if (vtype == ASCII_FILE_VIEWER || vtype == ASCII_FILES_VIEWER){
206*b97cf49bSBarry Smith     return MatView_SeqAdj_ASCII(A,viewer);
207*b97cf49bSBarry Smith   }
208*b97cf49bSBarry Smith   else if (vtype == BINARY_FILE_VIEWER) {
209*b97cf49bSBarry Smith     return MatView_SeqAdj_Binary(A,viewer);
210*b97cf49bSBarry Smith   }
211*b97cf49bSBarry Smith   else if (vtype == DRAW_VIEWER) {
212*b97cf49bSBarry Smith     return MatView_SeqAdj_Draw(A,viewer);
213*b97cf49bSBarry Smith   }
214*b97cf49bSBarry Smith   return 0;
215*b97cf49bSBarry Smith }
216*b97cf49bSBarry Smith 
217*b97cf49bSBarry Smith 
218*b97cf49bSBarry Smith #undef __FUNC__
219*b97cf49bSBarry Smith #define __FUNC__ "MatDestroy_SeqAdj"
220*b97cf49bSBarry Smith int MatDestroy_SeqAdj(PetscObject obj)
221*b97cf49bSBarry Smith {
222*b97cf49bSBarry Smith   Mat        A  = (Mat) obj;
223*b97cf49bSBarry Smith   Mat_SeqAdj *a = (Mat_SeqAdj *) A->data;
224*b97cf49bSBarry Smith 
225*b97cf49bSBarry Smith #if defined(PETSC_LOG)
226*b97cf49bSBarry Smith   PLogObjectState(obj,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz);
227*b97cf49bSBarry Smith #endif
228*b97cf49bSBarry Smith   if (a->diag) PetscFree(a->diag);
229*b97cf49bSBarry Smith   PetscFree(a->i);
230*b97cf49bSBarry Smith   PetscFree(a->j);
231*b97cf49bSBarry Smith   PetscFree(a);
232*b97cf49bSBarry Smith 
233*b97cf49bSBarry Smith   PLogObjectDestroy(A);
234*b97cf49bSBarry Smith   PetscHeaderDestroy(A);
235*b97cf49bSBarry Smith   return 0;
236*b97cf49bSBarry Smith }
237*b97cf49bSBarry Smith 
238*b97cf49bSBarry Smith 
239*b97cf49bSBarry Smith #undef __FUNC__
240*b97cf49bSBarry Smith #define __FUNC__ "MatSetOption_SeqAdj"
241*b97cf49bSBarry Smith int MatSetOption_SeqAdj(Mat A,MatOption op)
242*b97cf49bSBarry Smith {
243*b97cf49bSBarry Smith   Mat_SeqAdj *a = (Mat_SeqAdj *) A->data;
244*b97cf49bSBarry Smith 
245*b97cf49bSBarry Smith   if (op == MAT_STRUCTURALLY_SYMMETRIC) {
246*b97cf49bSBarry Smith     a->symmetric = PETSC_TRUE;
247*b97cf49bSBarry Smith   } else {
248*b97cf49bSBarry Smith     PLogInfo(A,"Info:MatSetOption_SeqAdj:Option ignored\n");
249*b97cf49bSBarry Smith   }
250*b97cf49bSBarry Smith   return 0;
251*b97cf49bSBarry Smith }
252*b97cf49bSBarry Smith 
253*b97cf49bSBarry Smith 
254*b97cf49bSBarry Smith /*
255*b97cf49bSBarry Smith      Adds diagonal pointers to sparse matrix structure.
256*b97cf49bSBarry Smith */
257*b97cf49bSBarry Smith 
258*b97cf49bSBarry Smith #undef __FUNC__
259*b97cf49bSBarry Smith #define __FUNC__ "MatMarkDiag_SeqAdj"
260*b97cf49bSBarry Smith int MatMarkDiag_SeqAdj(Mat A)
261*b97cf49bSBarry Smith {
262*b97cf49bSBarry Smith   Mat_SeqAdj *a = (Mat_SeqAdj *) A->data;
263*b97cf49bSBarry Smith   int        i,j, *diag, m = a->m;
264*b97cf49bSBarry Smith 
265*b97cf49bSBarry Smith   diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag);
266*b97cf49bSBarry Smith   PLogObjectMemory(A,(m+1)*sizeof(int));
267*b97cf49bSBarry Smith   for ( i=0; i<a->m; i++ ) {
268*b97cf49bSBarry Smith     for ( j=a->i[i]; j<a->i[i+1]; j++ ) {
269*b97cf49bSBarry Smith       if (a->j[j] == i) {
270*b97cf49bSBarry Smith         diag[i] = j;
271*b97cf49bSBarry Smith         break;
272*b97cf49bSBarry Smith       }
273*b97cf49bSBarry Smith     }
274*b97cf49bSBarry Smith   }
275*b97cf49bSBarry Smith   a->diag = diag;
276*b97cf49bSBarry Smith   return 0;
277*b97cf49bSBarry Smith }
278*b97cf49bSBarry Smith 
279*b97cf49bSBarry Smith 
280*b97cf49bSBarry Smith #undef __FUNC__
281*b97cf49bSBarry Smith #define __FUNC__ "MatGetInfo_SeqAdj"
282*b97cf49bSBarry Smith int MatGetInfo_SeqAdj(Mat A,MatInfoType flag,MatInfo *info)
283*b97cf49bSBarry Smith {
284*b97cf49bSBarry Smith   Mat_SeqAdj *a = (Mat_SeqAdj *) A->data;
285*b97cf49bSBarry Smith 
286*b97cf49bSBarry Smith   info->rows_global    = (double)a->m;
287*b97cf49bSBarry Smith   info->columns_global = (double)a->n;
288*b97cf49bSBarry Smith   info->rows_local     = (double)a->m;
289*b97cf49bSBarry Smith   info->columns_local  = (double)a->n;
290*b97cf49bSBarry Smith   info->block_size     = 1.0;
291*b97cf49bSBarry Smith   info->nz_allocated   = (double)a->nz;
292*b97cf49bSBarry Smith   info->nz_used        = (double)a->nz;
293*b97cf49bSBarry Smith   info->nz_unneeded    = 0.0;
294*b97cf49bSBarry Smith   /*  if (info->nz_unneeded != A->info.nz_unneeded)
295*b97cf49bSBarry Smith     printf("space descrepancy: maxnz-nz = %d, nz_unneeded = %d\n",(int)info->nz_unneeded,(int)A->info.nz_unneeded); */
296*b97cf49bSBarry Smith   info->assemblies     = 0.0;
297*b97cf49bSBarry Smith   info->mallocs        = 0.0;
298*b97cf49bSBarry Smith   info->memory         = A->mem;
299*b97cf49bSBarry Smith   if (A->factor) {
300*b97cf49bSBarry Smith     info->fill_ratio_given  = A->info.fill_ratio_given;
301*b97cf49bSBarry Smith     info->fill_ratio_needed = A->info.fill_ratio_needed;
302*b97cf49bSBarry Smith     info->factor_mallocs    = A->info.factor_mallocs;
303*b97cf49bSBarry Smith   } else {
304*b97cf49bSBarry Smith     info->fill_ratio_given  = 0;
305*b97cf49bSBarry Smith     info->fill_ratio_needed = 0;
306*b97cf49bSBarry Smith     info->factor_mallocs    = 0;
307*b97cf49bSBarry Smith   }
308*b97cf49bSBarry Smith   return 0;
309*b97cf49bSBarry Smith }
310*b97cf49bSBarry Smith 
311*b97cf49bSBarry Smith #undef __FUNC__
312*b97cf49bSBarry Smith #define __FUNC__ "MatGetSize_SeqAdj"
313*b97cf49bSBarry Smith int MatGetSize_SeqAdj(Mat A,int *m,int *n)
314*b97cf49bSBarry Smith {
315*b97cf49bSBarry Smith   Mat_SeqAdj *a = (Mat_SeqAdj *) A->data;
316*b97cf49bSBarry Smith   *m = a->m; *n = a->n;
317*b97cf49bSBarry Smith   return 0;
318*b97cf49bSBarry Smith }
319*b97cf49bSBarry Smith 
320*b97cf49bSBarry Smith #undef __FUNC__
321*b97cf49bSBarry Smith #define __FUNC__ "MatGetOwnershipRange_SeqAdj"
322*b97cf49bSBarry Smith int MatGetOwnershipRange_SeqAdj(Mat A,int *m,int *n)
323*b97cf49bSBarry Smith {
324*b97cf49bSBarry Smith   Mat_SeqAdj *a = (Mat_SeqAdj *) A->data;
325*b97cf49bSBarry Smith   *m = 0; *n = a->m;
326*b97cf49bSBarry Smith   return 0;
327*b97cf49bSBarry Smith }
328*b97cf49bSBarry Smith 
329*b97cf49bSBarry Smith #undef __FUNC__
330*b97cf49bSBarry Smith #define __FUNC__ "MatGetRow_SeqAdj"
331*b97cf49bSBarry Smith int MatGetRow_SeqAdj(Mat A,int row,int *nz,int **idx,Scalar **v)
332*b97cf49bSBarry Smith {
333*b97cf49bSBarry Smith   Mat_SeqAdj *a = (Mat_SeqAdj *) A->data;
334*b97cf49bSBarry Smith   int        *itmp;
335*b97cf49bSBarry Smith 
336*b97cf49bSBarry Smith   if (row < 0 || row >= a->m) SETERRQ(1,0,"Row out of range");
337*b97cf49bSBarry Smith 
338*b97cf49bSBarry Smith   *nz = a->i[row+1] - a->i[row];
339*b97cf49bSBarry Smith   if (v) *v = PETSC_NULL;
340*b97cf49bSBarry Smith   if (idx) {
341*b97cf49bSBarry Smith     itmp = a->j + a->i[row];
342*b97cf49bSBarry Smith     if (*nz) {
343*b97cf49bSBarry Smith       *idx = itmp;
344*b97cf49bSBarry Smith     }
345*b97cf49bSBarry Smith     else *idx = 0;
346*b97cf49bSBarry Smith   }
347*b97cf49bSBarry Smith   return 0;
348*b97cf49bSBarry Smith }
349*b97cf49bSBarry Smith 
350*b97cf49bSBarry Smith #undef __FUNC__
351*b97cf49bSBarry Smith #define __FUNC__ "MatRestoreRow_SeqAdj"
352*b97cf49bSBarry Smith int MatRestoreRow_SeqAdj(Mat A,int row,int *nz,int **idx,Scalar **v)
353*b97cf49bSBarry Smith {
354*b97cf49bSBarry Smith   return 0;
355*b97cf49bSBarry Smith }
356*b97cf49bSBarry Smith 
357*b97cf49bSBarry Smith #undef __FUNC__
358*b97cf49bSBarry Smith #define __FUNC__ "MatGetBlockSize_SeqAdj"
359*b97cf49bSBarry Smith int MatGetBlockSize_SeqAdj(Mat A, int *bs)
360*b97cf49bSBarry Smith {
361*b97cf49bSBarry Smith   *bs = 1;
362*b97cf49bSBarry Smith   return 0;
363*b97cf49bSBarry Smith }
364*b97cf49bSBarry Smith 
365*b97cf49bSBarry Smith #undef __FUNC__
366*b97cf49bSBarry Smith #define __FUNC__ "MatIncreaseOverlap_SeqAdj"
367*b97cf49bSBarry Smith int MatIncreaseOverlap_SeqAdj(Mat A, int is_max, IS *is, int ov)
368*b97cf49bSBarry Smith {
369*b97cf49bSBarry Smith   Mat_SeqAdj *a = (Mat_SeqAdj *) A->data;
370*b97cf49bSBarry Smith   int        row, i,j,k,l,m,n, *idx,ierr, *nidx, isz, val;
371*b97cf49bSBarry Smith   int        start, end, *ai, *aj;
372*b97cf49bSBarry Smith   char       *table;
373*b97cf49bSBarry Smith 
374*b97cf49bSBarry Smith   m     = a->m;
375*b97cf49bSBarry Smith   ai    = a->i;
376*b97cf49bSBarry Smith   aj    = a->j;
377*b97cf49bSBarry Smith 
378*b97cf49bSBarry Smith   if (ov < 0)  SETERRQ(1,0,"illegal overlap value used");
379*b97cf49bSBarry Smith 
380*b97cf49bSBarry Smith   table = (char *) PetscMalloc((m/BITSPERBYTE +1)*sizeof(char)); CHKPTRQ(table);
381*b97cf49bSBarry Smith   nidx  = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(nidx);
382*b97cf49bSBarry Smith 
383*b97cf49bSBarry Smith   for ( i=0; i<is_max; i++ ) {
384*b97cf49bSBarry Smith     /* Initialize the two local arrays */
385*b97cf49bSBarry Smith     isz  = 0;
386*b97cf49bSBarry Smith     PetscMemzero(table,(m/BITSPERBYTE +1)*sizeof(char));
387*b97cf49bSBarry Smith 
388*b97cf49bSBarry Smith     /* Extract the indices, assume there can be duplicate entries */
389*b97cf49bSBarry Smith     ierr = ISGetIndices(is[i],&idx);  CHKERRQ(ierr);
390*b97cf49bSBarry Smith     ierr = ISGetSize(is[i],&n);  CHKERRQ(ierr);
391*b97cf49bSBarry Smith 
392*b97cf49bSBarry Smith     /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */
393*b97cf49bSBarry Smith     for ( j=0; j<n ; ++j){
394*b97cf49bSBarry Smith       if(!BT_LOOKUP(table, idx[j])) { nidx[isz++] = idx[j];}
395*b97cf49bSBarry Smith     }
396*b97cf49bSBarry Smith     ierr = ISRestoreIndices(is[i],&idx);  CHKERRQ(ierr);
397*b97cf49bSBarry Smith     ierr = ISDestroy(is[i]); CHKERRQ(ierr);
398*b97cf49bSBarry Smith 
399*b97cf49bSBarry Smith     k = 0;
400*b97cf49bSBarry Smith     for ( j=0; j<ov; j++){ /* for each overlap */
401*b97cf49bSBarry Smith       n = isz;
402*b97cf49bSBarry Smith       for ( ; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */
403*b97cf49bSBarry Smith         row   = nidx[k];
404*b97cf49bSBarry Smith         start = ai[row];
405*b97cf49bSBarry Smith         end   = ai[row+1];
406*b97cf49bSBarry Smith         for ( l = start; l<end ; l++){
407*b97cf49bSBarry Smith           val = aj[l];
408*b97cf49bSBarry Smith           if (!BT_LOOKUP(table,val)) {nidx[isz++] = val;}
409*b97cf49bSBarry Smith         }
410*b97cf49bSBarry Smith       }
411*b97cf49bSBarry Smith     }
412*b97cf49bSBarry Smith     ierr = ISCreateGeneral(PETSC_COMM_SELF, isz, nidx, (is+i)); CHKERRQ(ierr);
413*b97cf49bSBarry Smith   }
414*b97cf49bSBarry Smith   PetscFree(table);
415*b97cf49bSBarry Smith   PetscFree(nidx);
416*b97cf49bSBarry Smith   return 0;
417*b97cf49bSBarry Smith }
418*b97cf49bSBarry Smith 
419*b97cf49bSBarry Smith #undef __FUNC__
420*b97cf49bSBarry Smith #define __FUNC__ "MatEqual_SeqAdj"
421*b97cf49bSBarry Smith int MatEqual_SeqAdj(Mat A,Mat B, PetscTruth* flg)
422*b97cf49bSBarry Smith {
423*b97cf49bSBarry Smith   Mat_SeqAdj *a = (Mat_SeqAdj *)A->data, *b = (Mat_SeqAdj *)B->data;
424*b97cf49bSBarry Smith 
425*b97cf49bSBarry Smith   if (B->type != MATSEQADJ) SETERRQ(1,0,"Matrices must be same type");
426*b97cf49bSBarry Smith 
427*b97cf49bSBarry Smith   /* If the  matrix dimensions are not equal, or no of nonzeros */
428*b97cf49bSBarry Smith   if ((a->m != b->m ) || (a->n !=b->n) ||( a->nz != b->nz)) {
429*b97cf49bSBarry Smith     *flg = PETSC_FALSE; return 0;
430*b97cf49bSBarry Smith   }
431*b97cf49bSBarry Smith 
432*b97cf49bSBarry Smith   /* if the a->i are the same */
433*b97cf49bSBarry Smith   if (PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int))) {
434*b97cf49bSBarry Smith     *flg = PETSC_FALSE; return 0;
435*b97cf49bSBarry Smith   }
436*b97cf49bSBarry Smith 
437*b97cf49bSBarry Smith   /* if a->j are the same */
438*b97cf49bSBarry Smith   if (PetscMemcmp(a->j, b->j, (a->nz)*sizeof(int))) {
439*b97cf49bSBarry Smith     *flg = PETSC_FALSE; return 0;
440*b97cf49bSBarry Smith   }
441*b97cf49bSBarry Smith 
442*b97cf49bSBarry Smith   *flg = PETSC_TRUE;
443*b97cf49bSBarry Smith   return 0;
444*b97cf49bSBarry Smith }
445*b97cf49bSBarry Smith 
446*b97cf49bSBarry Smith #undef __FUNC__
447*b97cf49bSBarry Smith #define __FUNC__ "MatPermute_SeqAdj"
448*b97cf49bSBarry Smith int MatPermute_SeqAdj(Mat A, IS rowp, IS colp, Mat *B)
449*b97cf49bSBarry Smith {
450*b97cf49bSBarry Smith   Mat_SeqAdj *a = (Mat_SeqAdj *) A->data;
451*b97cf49bSBarry Smith   Scalar     *vwork;
452*b97cf49bSBarry Smith   int        i, ierr, nz = a->nz, m = a->m, n = a->n, *cwork,*ii,*jj;
453*b97cf49bSBarry Smith   int        *row,*col,j,*lens;
454*b97cf49bSBarry Smith   IS         icolp,irowp;
455*b97cf49bSBarry Smith 
456*b97cf49bSBarry Smith   ierr = ISInvertPermutation(rowp,&irowp); CHKERRQ(ierr);
457*b97cf49bSBarry Smith   ierr = ISGetIndices(irowp,&row); CHKERRQ(ierr);
458*b97cf49bSBarry Smith   ierr = ISInvertPermutation(colp,&icolp); CHKERRQ(ierr);
459*b97cf49bSBarry Smith   ierr = ISGetIndices(icolp,&col); CHKERRQ(ierr);
460*b97cf49bSBarry Smith 
461*b97cf49bSBarry Smith   /* determine lengths of permuted rows */
462*b97cf49bSBarry Smith   lens = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(lens);
463*b97cf49bSBarry Smith   for (i=0; i<m; i++ ) {
464*b97cf49bSBarry Smith     lens[row[i]] = a->i[i+1] - a->i[i];
465*b97cf49bSBarry Smith   }
466*b97cf49bSBarry Smith 
467*b97cf49bSBarry Smith   ii = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(ii);
468*b97cf49bSBarry Smith   jj = (int *) PetscMalloc((nz+1)*sizeof(int));CHKPTRQ(jj);
469*b97cf49bSBarry Smith   ii[0] = 0;
470*b97cf49bSBarry Smith   for (i=1; i<=m; i++ ) {
471*b97cf49bSBarry Smith     ii[i] = ii[i-1] + lens[i-1];
472*b97cf49bSBarry Smith   }
473*b97cf49bSBarry Smith   PetscFree(lens);
474*b97cf49bSBarry Smith 
475*b97cf49bSBarry Smith   for (i=0; i<m; i++) {
476*b97cf49bSBarry Smith     ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
477*b97cf49bSBarry Smith     for (j=0; j<nz; j++ ) { jj[j+ii[row[i]]] = col[cwork[j]];}
478*b97cf49bSBarry Smith     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
479*b97cf49bSBarry Smith   }
480*b97cf49bSBarry Smith 
481*b97cf49bSBarry Smith   ierr = MatCreateSeqAdj(A->comm,m,n,ii,jj,B);CHKERRQ(ierr);
482*b97cf49bSBarry Smith 
483*b97cf49bSBarry Smith   ierr = ISRestoreIndices(irowp,&row); CHKERRQ(ierr);
484*b97cf49bSBarry Smith   ierr = ISRestoreIndices(icolp,&col); CHKERRQ(ierr);
485*b97cf49bSBarry Smith   ierr = ISDestroy(irowp); CHKERRQ(ierr);
486*b97cf49bSBarry Smith   ierr = ISDestroy(icolp); CHKERRQ(ierr);
487*b97cf49bSBarry Smith   return 0;
488*b97cf49bSBarry Smith }
489*b97cf49bSBarry Smith 
490*b97cf49bSBarry Smith /* -------------------------------------------------------------------*/
491*b97cf49bSBarry Smith static struct _MatOps MatOps = {0,
492*b97cf49bSBarry Smith        MatGetRow_SeqAdj,MatRestoreRow_SeqAdj,
493*b97cf49bSBarry Smith        0,0,
494*b97cf49bSBarry Smith        0,0,
495*b97cf49bSBarry Smith        0,0,
496*b97cf49bSBarry Smith        0,0,
497*b97cf49bSBarry Smith        0,0,
498*b97cf49bSBarry Smith        0,
499*b97cf49bSBarry Smith        0,
500*b97cf49bSBarry Smith        MatGetInfo_SeqAdj,MatEqual_SeqAdj,
501*b97cf49bSBarry Smith        0,0,0,
502*b97cf49bSBarry Smith        0,0,
503*b97cf49bSBarry Smith        0,
504*b97cf49bSBarry Smith        MatSetOption_SeqAdj,0,0,
505*b97cf49bSBarry Smith        0,0,0,0,
506*b97cf49bSBarry Smith        MatGetSize_SeqAdj,MatGetSize_SeqAdj,MatGetOwnershipRange_SeqAdj,
507*b97cf49bSBarry Smith        0,0,
508*b97cf49bSBarry Smith        0,0,
509*b97cf49bSBarry Smith        0,0,0,
510*b97cf49bSBarry Smith        0,0,0,
511*b97cf49bSBarry Smith        0,MatIncreaseOverlap_SeqAdj,
512*b97cf49bSBarry Smith        0,0,
513*b97cf49bSBarry Smith        0,
514*b97cf49bSBarry Smith        0,0,0,
515*b97cf49bSBarry Smith        0,
516*b97cf49bSBarry Smith        MatGetBlockSize_SeqAdj,
517*b97cf49bSBarry Smith        MatGetRowIJ_SeqAdj,
518*b97cf49bSBarry Smith        MatRestoreRowIJ_SeqAdj,
519*b97cf49bSBarry Smith        0,
520*b97cf49bSBarry Smith        0,
521*b97cf49bSBarry Smith        0,
522*b97cf49bSBarry Smith        0,
523*b97cf49bSBarry Smith        0,
524*b97cf49bSBarry Smith        MatPermute_SeqAdj};
525*b97cf49bSBarry Smith 
526*b97cf49bSBarry Smith 
527*b97cf49bSBarry Smith #undef __FUNC__
528*b97cf49bSBarry Smith #define __FUNC__ "MatCreateSeqAdj"
529*b97cf49bSBarry Smith /*@C
530*b97cf49bSBarry Smith    MatCreateSeqAdj - Creates a sparse matrix representing an adjacency list.
531*b97cf49bSBarry Smith      The matrix does not have numerical values associated with it, but is
532*b97cf49bSBarry Smith      intended for ordering (to reduce bandwidth etc) and partitioning.
533*b97cf49bSBarry Smith 
534*b97cf49bSBarry Smith    Input Parameters:
535*b97cf49bSBarry Smith .  comm - MPI communicator, set to PETSC_COMM_SELF
536*b97cf49bSBarry Smith .  m - number of rows
537*b97cf49bSBarry Smith .  n - number of columns
538*b97cf49bSBarry Smith .  i - the indices into j for the start of each row
539*b97cf49bSBarry Smith .  j - the column indices for each row (sorted for each row)
540*b97cf49bSBarry Smith        The indices in i and j start with zero NOT one.
541*b97cf49bSBarry Smith 
542*b97cf49bSBarry Smith    Output Parameter:
543*b97cf49bSBarry Smith .  A - the matrix
544*b97cf49bSBarry Smith 
545*b97cf49bSBarry Smith    Notes: You must free the ii and jj arrays yourself. PETSc will free them
546*b97cf49bSBarry Smith    when the matrix is destroyed.
547*b97cf49bSBarry Smith 
548*b97cf49bSBarry Smith .  MatSetOptions() possible values - MAT_STRUCTURALLY_SYMMETRIC
549*b97cf49bSBarry Smith 
550*b97cf49bSBarry Smith .seealso: MatCreate(), MatCreateMPIADJ(), MatGetReordering()
551*b97cf49bSBarry Smith @*/
552*b97cf49bSBarry Smith int MatCreateSeqAdj(MPI_Comm comm,int m,int n,int *i,int *j, Mat *A)
553*b97cf49bSBarry Smith {
554*b97cf49bSBarry Smith   Mat        B;
555*b97cf49bSBarry Smith   Mat_SeqAdj *b;
556*b97cf49bSBarry Smith   int        ierr, flg,size;
557*b97cf49bSBarry Smith 
558*b97cf49bSBarry Smith   MPI_Comm_size(comm,&size);
559*b97cf49bSBarry Smith   if (size > 1) SETERRQ(1,0,"Comm must be of size 1");
560*b97cf49bSBarry Smith 
561*b97cf49bSBarry Smith   *A                  = 0;
562*b97cf49bSBarry Smith   PetscHeaderCreate(B,_p_Mat,MAT_COOKIE,MATSEQADJ,comm,MatDestroy,MatView);
563*b97cf49bSBarry Smith   PLogObjectCreate(B);
564*b97cf49bSBarry Smith   B->data             = (void *) (b = PetscNew(Mat_SeqAdj)); CHKPTRQ(b);
565*b97cf49bSBarry Smith   PetscMemzero(b,sizeof(Mat_SeqAdj));
566*b97cf49bSBarry Smith   PetscMemcpy(&B->ops,&MatOps,sizeof(struct _MatOps));
567*b97cf49bSBarry Smith   B->destroy          = MatDestroy_SeqAdj;
568*b97cf49bSBarry Smith   B->view             = MatView_SeqAdj;
569*b97cf49bSBarry Smith   B->factor           = 0;
570*b97cf49bSBarry Smith   B->lupivotthreshold = 1.0;
571*b97cf49bSBarry Smith   B->mapping          = 0;
572*b97cf49bSBarry Smith   B->assembled        = PETSC_FALSE;
573*b97cf49bSBarry Smith 
574*b97cf49bSBarry Smith   b->m = m; B->m = m; B->M = m;
575*b97cf49bSBarry Smith   b->n = n; B->n = n; B->N = n;
576*b97cf49bSBarry Smith 
577*b97cf49bSBarry Smith   b->j  = j;
578*b97cf49bSBarry Smith   b->i  = i;
579*b97cf49bSBarry Smith 
580*b97cf49bSBarry Smith   b->nz               = i[m];
581*b97cf49bSBarry Smith   b->diag             = 0;
582*b97cf49bSBarry Smith   b->symmetric        = PETSC_FALSE;
583*b97cf49bSBarry Smith 
584*b97cf49bSBarry Smith   *A = B;
585*b97cf49bSBarry Smith 
586*b97cf49bSBarry Smith   ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr);
587*b97cf49bSBarry Smith   if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); }
588*b97cf49bSBarry Smith   ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
589*b97cf49bSBarry Smith   ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
590*b97cf49bSBarry Smith   return 0;
591*b97cf49bSBarry Smith }
592*b97cf49bSBarry Smith 
593*b97cf49bSBarry Smith #undef __FUNC__
594*b97cf49bSBarry Smith #define __FUNC__ "MatLoad_SeqAdj"
595*b97cf49bSBarry Smith int MatLoad_SeqAdj(Viewer viewer,MatType type,Mat *A)
596*b97cf49bSBarry Smith {
597*b97cf49bSBarry Smith   int          i, nz, ierr, fd, header[4],size,*rowlengths = 0,M,N,*ii,*jj;
598*b97cf49bSBarry Smith   MPI_Comm     comm;
599*b97cf49bSBarry Smith 
600*b97cf49bSBarry Smith   PetscObjectGetComm((PetscObject) viewer,&comm);
601*b97cf49bSBarry Smith   MPI_Comm_size(comm,&size);
602*b97cf49bSBarry Smith   if (size > 1) SETERRQ(1,0,"view must have one processor");
603*b97cf49bSBarry Smith   ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr);
604*b97cf49bSBarry Smith   ierr = PetscBinaryRead(fd,header,4,BINARY_INT); CHKERRQ(ierr);
605*b97cf49bSBarry Smith   if (header[0] != MAT_COOKIE) SETERRQ(1,0,"not matrix object in file");
606*b97cf49bSBarry Smith   M = header[1]; N = header[2]; nz = header[3];
607*b97cf49bSBarry Smith 
608*b97cf49bSBarry Smith   /* read in row lengths */
609*b97cf49bSBarry Smith   rowlengths = (int*) PetscMalloc( M*sizeof(int) ); CHKPTRQ(rowlengths);
610*b97cf49bSBarry Smith   ierr = PetscBinaryRead(fd,rowlengths,M,BINARY_INT); CHKERRQ(ierr);
611*b97cf49bSBarry Smith 
612*b97cf49bSBarry Smith   /* create our matrix */
613*b97cf49bSBarry Smith   ii = (int *) PetscMalloc( (M+1)*sizeof(int) );CHKPTRQ(ii);
614*b97cf49bSBarry Smith   jj = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(jj);
615*b97cf49bSBarry Smith 
616*b97cf49bSBarry Smith   /* read in column indices and adjust for Fortran indexing*/
617*b97cf49bSBarry Smith   ierr = PetscBinaryRead(fd,jj,nz,BINARY_INT); CHKERRQ(ierr);
618*b97cf49bSBarry Smith 
619*b97cf49bSBarry Smith   /* set matrix "i" values */
620*b97cf49bSBarry Smith   ii[0] = 0;
621*b97cf49bSBarry Smith   for ( i=1; i<= M; i++ ) {
622*b97cf49bSBarry Smith     ii[i]      = ii[i-1] + rowlengths[i-1];
623*b97cf49bSBarry Smith   }
624*b97cf49bSBarry Smith   PetscFree(rowlengths);
625*b97cf49bSBarry Smith 
626*b97cf49bSBarry Smith   ierr = MatCreateSeqAdj(comm,M,N,ii,jj,A); CHKERRQ(ierr);
627*b97cf49bSBarry Smith   return 0;
628*b97cf49bSBarry Smith }
629*b97cf49bSBarry Smith 
630*b97cf49bSBarry Smith 
631