NeoPZ
gegra.cpp
Go to the documentation of this file.
1 #include <iostream>
2 using namespace std;
3 #include <stdlib.h>
4 #include "sloan.h"
5 
7 int gegra_(int64_t *n,int64_t *ne,int64_t *,int64_t *npn,int64_t *xnpn,int64_t *iadj,int64_t *adj,int64_t *xadj,int *nop)
8 {
9  /* Format strings */
10  const char *fmt_10900 = "(\0020%%%E01-GEGRA \002,//,1x,\002CANNOT ASSE\
11 MBLE NODE ADJACENCY LIST\002,//,1x,\002CHECK NPN AND XNPN ARRAYS\002)";
12  /* System generated locals */
13  int64_t i__1, i__2, i__3, i__4;
14  /* Local variables */
15  int64_t i, j, k, l, m, nodej, nodek, jstop, lstop, mstop, jstrt, jrtst, lstrt, mstrt, nen1;
16 
17 /* INPUT: */
18 /* ------ */
19 /* N - Number of nodes in graph (finite element mesh) */
20 /* NE - Number of elements in finte element mesh */
21 /* INPN - Length of NPN = XNPN(NE+1)-1 */
22 /* NPN - List of node numbers for each element */
23 /* XNPN - Index vector for npn */
24 /* - nodes for element I are found in NPN(J), where */
25 /* J=XNPN(I), XNPN(I+1), ..., XNPN(I+1)-1 */
26 /* IADJ - Length of vector ADJ */
27 /* - Set IADJ=NE*NEN*(NEN-1) for a mesh of simple type of */
28 /* - element with NEN nodes */
29 /* - IADJ=(NEN(1)*(NEN(1)-1)+,.....,+NEN(NE)*(NEN(NE)-1)) */
30 /* - for a mesh of elements with varying numbers of nodes */
31 /* ADJ - Undefined */
32 /* XADJ - Undefined */
33 
34 /* OUTPUT : */
35 /* -------- */
36 /* N - Unchanged */
37 /* NE - Unchanged */
38 /* INPN - Unchanged */
39 /* NPN - Unchanged */
40 /* XNPN - Unchanged */
41 /* IADJ - Modified = XADJ(N+1)-1 longueur reelle */
42 /* ADJ - Adjacency list for all nodes in graph */
43 /* - List of length 2E where E is the number of edges in */
44 /* the graph (note that 2E = XADJ(N+1)-1) */
45 /* XADJ - Index vector for ADJ */
46 /* - Nodes adjacent to node I are found in ADJ(J), where */
47 /* - J = XADJ(I),XADJ(I)+1, ..., XADJ(I+1)-1 */
48 /* - Degree of node I give by XADJ(I+1)-XADJ(I) */
49 
50 /* NOTES: */
51 /* ------ */
52 /* This routine typically requires about 25 percent elbow room for */
53 /* assembling the ADJ list (i.e. IADJ/2E is typically around 1.25). */
54 /* In some cases, the elbow room may be larger (IADJ/2E is slightly */
55 /* less than 2 for the 3-nodes triangle) and in order cases it may be
56 */
57 /* zero (IADJ/2E = 1 for bar elements) */
58 
59 
60 /* PROGRAMMER: Scott Sloan */
61 /* ----------- */
62 
63 /* LAST MODIFIED: 10 March 1989 Scott Sloan */
64 /* ***********************************************************************
65  */
66 
67 /* Initialise the adjacency list and its index vector */
68 
69 /* Parameter adjustments */
70 
71  --xadj;
72  --xnpn;
73  --npn;
74  --adj;
75 
76  /* Function Body */
77  i__1 = *iadj;
78  for (i = 1; i <= i__1; ++i)
79  {
80  adj[i] = 0;
81 /* L5: */
82  }
83  i__1 = *n;
84  for (i = 1; i <= i__1; ++i)
85  {
86  xadj[i] = 0;
87 /* L10: */
88  }
89 
90 /* Estimate the degree of each node (always an overestimate) */
91 
92  i__1 = *ne;
93  for (i = 1; i <= i__1; ++i)
94  {
95  jstrt = xnpn[i];
96  jstop = xnpn[i + 1] - 1;
97  nen1 = jstop - jstrt;
98  i__2 = jstop;
99  for (j = jstrt; j <= i__2; ++j)
100  {
101  nodej = npn[j];
102  xadj[nodej] += nen1;
103 /* L20: */
104  }
105 /* L30: */
106  }
107 
108 /* Reconstruct XADJ to point to start of each set of neighbours */
109 
110 
111  l=1;
112  i__1 = *n;
113  for (i = 1; i <= i__1; ++i)
114  {
115  l += xadj[i];
116  xadj[i] = l - xadj[i];
117 /* L40: */
118  }
119  xadj[*n + 1] = l;
120 
121 /* Form adjency list (which may contain zeros) */
122 
123  i__1 = *ne;
124  for (i = 1; i <= i__1; ++i)
125  {
126  jrtst = xnpn[i];
127  jstop = xnpn[i + 1] - 1;
128  i__2 = jstop - 1;
129  for (j = jrtst; j <= i__2; ++j)
130  {
131  nodej = npn[j];
132  lstrt = xadj[nodej];
133  lstop = xadj[nodej + 1] - 1;
134  i__3 = jstop;
135  for (k = j + 1; k <= i__3; ++k)
136  {
137  nodek = npn[k];
138  i__4 = lstop;
139  for (l = lstrt; l <= i__4; ++l)
140  {
141  if (adj[l] == nodek)
142  {
143  goto L70;
144  }
145  if (adj[l] == 0)
146  {
147  goto L55;
148  }
149 /* L50: */
150  }
151  cerr << fmt_10900;
152  *nop = 900;
153  return 0;
154  L55:
155  adj[l] = nodek;
156  mstrt = xadj[nodek];
157  mstop = xadj[nodek + 1] - 1;
158  i__4 = mstop;
159  for (m = mstrt; m <= i__4; ++m)
160  {
161  if (adj[m] == 0)
162  {
163  goto L65;
164  }
165 /* L60: */
166  }
167  cerr << fmt_10900;
168  *nop = 900;
169  return 0;
170  L65:
171  adj[m] = nodej;
172  L70:
173  ;
174  }
175 /* L80: */
176  }
177 /* L90: */
178  }
179 
180 /* Strip any zeros from adjacency list */
181 
182  k = 0;
183  jstrt = 1;
184  i__1 = *n;
185  for (i = 1; i <= i__1; ++i)
186  {
187  jstop = xadj[i + 1] - 1;
188  i__2 = jstop;
189  for (j = jstrt; j <= i__2; ++j)
190  {
191  if (adj[j] == 0)
192  {
193  goto L105;
194  }
195  ++k;
196  adj[k] = adj[j];
197 /* L100: */
198  }
199 L105:
200  xadj[i + 1] = k + 1;
201  jstrt = jstop + 1;
202 /* L110: */
203  }
204  *iadj = xadj[*n + 1] - 1;
205  *iadj = (*iadj > 1) ? *iadj : 1;
206 
207  return 0;
208 } /* gegra_ */
clarg::argString m("-m", "input matrix file name (text format)", "matrix.txt")
int gegra_(int64_t *n, int64_t *ne, int64_t *, int64_t *npn, int64_t *xnpn, int64_t *iadj, int64_t *adj, int64_t *xadj, int *nop)
Purpose: Form adjacency list for a graph corresponding to a finite element mesh.
Definition: gegra.cpp:7