/[ascend]/trunk/ascend/system/graph.c
ViewVC logotype

Contents of /trunk/ascend/system/graph.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2423 - (show annotations) (download) (as text)
Wed Mar 23 04:42:11 2011 UTC (11 years, 3 months ago) by jpye
File MIME type: text/x-csrc
File size: 8942 byte(s)
Changes from Divyanshu Bandil to add support for dlopening of Graphviz, enabling it to become an optional component at install-time.
1 /* ASCEND modelling environment
2 Copyright (C) 2007 Carnegie Mellon University
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18 *//** @file
19 System graph output
20
21 Use variable and relation filters to generate a graph between the selected
22 vars and rels, by querying their incidence data. Write the graph in DOT
23 format to the provided FILE*.
24
25 by John Pye, March 2007
26 */
27
28 #ifdef HAVE_GRAPHVIZ_BOOLEAN
29 # define HAVE_BOOLEAN
30 #endif
31 #include <ascend/general/platform.h>
32
33 /*#ifdef WITH_GRAPHVIZ
34 # ifdef __WIN32__
35 # include <gvc.h>
36 # else
37 # include <graphviz/gvc.h>
38 # endif
39 # define HAVE_BOOLEAN
40 #endif*/
41
42 boolean X;
43
44 #include "graph.h"
45 #include "slv_client.h"
46 #include "incidence.h"
47 #include <ascend/general/ascMalloc.h>
48 #include <ascend/general/panic.h>
49 #include <dlfcn.h>
50 #include <graphviz/gvc.h>
51
52 int system_write_graph(slv_system_t sys
53 , FILE *fp
54 , const char *format
55 ){
56 incidence_vars_t id;
57 build_incidence_data(sys, &id);
58
59 void * handle;
60 handle = dlopen("libgvc.so",RTLD_NOW);
61 if(handle==NULL)
62 {
63 printf("Graphviz was not found on your system");
64 return 1;
65 }
66
67 Agraph_t *g;
68 Agraph_t *(*agop)(char* , int);
69
70 GVC_t *gvc;
71 GVC_t *(*gvConte)();
72
73 void (*agnodeat) (Agraph_t* , char* , char*);
74
75 *(void **) (&gvConte) = dlsym(handle,"gvContext");
76 *(void **) (&agop) = dlsym(handle,"agopen");
77 *(void **) (&agnodeat) = dlsym(handle,"agnodeattr");
78
79
80 unsigned edgecount = 0;
81 unsigned nodecount = 0;
82
83 gvc = (*gvConte)();
84 g = (*agop)("g",AGDIGRAPH);
85 (*agnodeat)(g,"shape","ellipse");
86 (*agnodeat)(g,"label","");
87 (*agnodeat)(g,"color","");
88 (*agnodeat)(g,"style","");
89
90 char temp[200];
91
92 /* first create nodes for the relations */
93 unsigned i;
94 Agnode_t *n, *m;
95 Agnode_t *(*agno)(Agraph_t* , char*);
96 void (*ags) (Agnode_t* , char* , char*);
97
98 *(void **) (&agno) = dlsym(handle,"agnode");
99 *(void **) (&ags) = dlsym(handle,"agset");
100
101
102 for(i=0; i < id.neqn; ++i){
103 char *relname;
104 relname = rel_make_name(sys,id.rlist[i]);
105 sprintf(temp,"r%d",rel_sindex(id.rlist[i]));
106 n = (*agno)(g,temp);
107 (*ags)(n,"label",relname);
108 if(rel_satisfied(id.rlist[i])){
109 (*ags)(n,"style","filled");
110 (*ags)(n,"color","blue");
111 }
112 ASC_FREE(relname);
113 nodecount++;
114 }
115
116 /* now create nodes for the variables */
117 unsigned j;
118 for(j=0; j < id.nvar; ++j){
119 char *varname;
120 varname = var_make_name(sys,id.vlist[j]);
121 sprintf(temp,"v%d",var_sindex(id.vlist[j]));
122 n = (*agno)(g,temp);
123 (*ags)(n,"label",varname);
124 (*ags)(n, "shape", "box");
125 if(var_fixed(id.vlist[j])){
126 CONSOLE_DEBUG("VAR '%s' IS FIXED",varname);
127 (*ags)(n,"style","filled");
128 (*ags)(n,"color","green");
129 }
130 if(!var_active(id.vlist[j])){
131 CONSOLE_DEBUG("VAR '%s' IS FIXED",varname);
132 (*ags)(n,"style","filled");
133 (*ags)(n,"color","gray");
134 }
135 ASC_FREE(varname);
136 nodecount++;
137 }
138
139 /* now create edges */
140 const struct var_variable **ivars;
141 unsigned niv;
142 char reltemp[200];
143 Agedge_t *e;
144 Agedge_t *(*aged)(Agraph_t* , Agnode_t*, Agnode_t*);
145
146 *(void **) (&aged) = dlsym(handle,"agedge");
147
148 for(i=0; i < id.nprow; ++i){
149 ivars = rel_incidence_list(id.rlist[i]);
150 niv = rel_n_incidences(id.rlist[i]);
151 sprintf(reltemp,"r%d",rel_sindex(id.rlist[i]));
152 char *relname;
153 relname = rel_make_name(sys,id.rlist[i]);
154 CONSOLE_DEBUG("rel = '%s'",relname);
155 ASC_FREE(relname);
156 for(j=0; j < niv; ++j){
157 const struct var_variable *v;
158 v = ivars[j];
159 sprintf(temp,"v%d",var_sindex(v));
160 n = (*agno)(g, reltemp);
161 m = (*agno)(g, temp);
162
163 if(id.v2pc[var_sindex(v)]==id.e2pr[rel_sindex(id.rlist[i])]){
164 e = (*aged)(g,n,m); /* from rel to var */
165 }else{
166 e = (*aged)(g,m,n); /* from var to rel */
167 }
168 edgecount++;
169 }
170 }
171
172 if(nodecount > 300 || edgecount > 300){
173 ERROR_REPORTER_HERE(ASC_USER_ERROR,"Graph is too complex, will not launch GraphViz (%d nodes, %d edges)", nodecount, edgecount);
174 return 1;
175 }
176
177
178 void (*gvLayo)(GVC_t* , Agraph_t*, char*);
179 void (*gvRend)(GVC_t* , Agraph_t*, char*, FILE*);
180
181 *(void **) (&gvLayo) = dlsym(handle,"gvLayout");
182 *(void **) (&gvRend) = dlsym(handle,"gvRender");
183
184
185 (*gvLayo)(gvc, g, "dot");
186 (*gvRend)(gvc, g, (char*)format, fp);
187
188 printf("\nErrors encountered %s\n",(*dlerror)());
189 dlclose(handle);
190
191 #if 0//def WITH_GRAPHVIZ
192
193
194 Agraph_t *g;
195 GVC_t *gvc;
196
197 unsigned edgecount = 0;
198 unsigned nodecount = 0;
199
200 gvc = gvContext();
201 g = agopen("g",AGDIGRAPH);
202 agnodeattr(g,"shape","ellipse");
203 agnodeattr(g,"label","");
204 agnodeattr(g,"color","");
205 agnodeattr(g,"style","");
206
207 char temp[200];
208
209 /* first create nodes for the relations */
210 unsigned i;
211 Agnode_t *n, *m;
212 for(i=0; i < id.neqn; ++i){
213 char *relname;
214 relname = rel_make_name(sys,id.rlist[i]);
215 sprintf(temp,"r%d",rel_sindex(id.rlist[i]));
216 n = agnode(g,temp);
217 agset(n,"label",relname);
218 if(rel_satisfied(id.rlist[i])){
219 agset(n,"style","filled");
220 agset(n,"color","blue");
221 }
222 ASC_FREE(relname);
223 nodecount++;
224 }
225
226 /* now create nodes for the variables */
227 unsigned j;
228 for(j=0; j < id.nvar; ++j){
229 char *varname;
230 varname = var_make_name(sys,id.vlist[j]);
231 sprintf(temp,"v%d",var_sindex(id.vlist[j]));
232 n = agnode(g,temp);
233 agset(n,"label",varname);
234 agset(n, "shape", "box");
235 if(var_fixed(id.vlist[j])){
236 CONSOLE_DEBUG("VAR '%s' IS FIXED",varname);
237 agset(n,"style","filled");
238 agset(n,"color","green");
239 }
240 if(!var_active(id.vlist[j])){
241 CONSOLE_DEBUG("VAR '%s' IS FIXED",varname);
242 agset(n,"style","filled");
243 agset(n,"color","gray");
244 }
245 ASC_FREE(varname);
246 nodecount++;
247 }
248
249 /* now create edges */
250 const struct var_variable **ivars;
251 unsigned niv;
252 char reltemp[200];
253 struct Agedge_t *e;
254 for(i=0; i < id.nprow; ++i){
255 ivars = rel_incidence_list(id.rlist[i]);
256 niv = rel_n_incidences(id.rlist[i]);
257 sprintf(reltemp,"r%d",rel_sindex(id.rlist[i]));
258 char *relname;
259 relname = rel_make_name(sys,id.rlist[i]);
260 CONSOLE_DEBUG("rel = '%s'",relname);
261 ASC_FREE(relname);
262 for(j=0; j < niv; ++j){
263 const struct var_variable *v;
264 v = ivars[j];
265 sprintf(temp,"v%d",var_sindex(v));
266 n = agnode(g, reltemp);
267 m = agnode(g, temp);
268
269 if(id.v2pc[var_sindex(v)]==id.e2pr[rel_sindex(id.rlist[i])]){
270 e = agedge(g,n,m); /* from rel to var */
271 }else{
272 e = agedge(g,m,n); /* from var to rel */
273 }
274 edgecount++;
275 }
276 }
277
278 if(nodecount > 300 || edgecount > 300){
279 ERROR_REPORTER_HERE(ASC_USER_ERROR,"Graph is too complex, will not launch GraphViz (%d nodes, %d edges)", nodecount, edgecount);
280 return 1;
281 }
282
283 gvLayout(gvc, g, "dot");
284 gvRender(gvc, g, (char*)format, fp); */
285
286 #else
287 // ERROR_REPORTER_HERE(ASC_PROG_ERR,"Function system_write_graph not available (GraphViz not present at build-time)");
288 // return 1; /* error */
289 #endif
290
291 #if 0
292 int nr,nsr,nv,nsv,niv;
293 int i,j;
294 struct rel_relation **srels;
295 struct var_variable **svars, **ivars;
296 char *relname, *varname;
297
298 CONSOLE_DEBUG("Writing graph...");
299 asc_assert(fp!=NULL);
300
301 CONSOLE_DEBUG("FP = %p",fp);
302 fprintf(fp,"digraph G{\n");
303
304 /* first create nodes for the rels */
305 nr = slv_count_solvers_rels(sys,rfilter);
306 nsr = slv_get_num_solvers_rels(sys);
307 srels = slv_get_solvers_rel_list(sys);
308 fprintf(fp,"\n\n\t/* %d relations */\n\n",nr);
309 for(i=0; i<nsr; ++i){
310 if(rel_apply_filter(srels[i],rfilter)){
311 relname = rel_make_name(sys,srels[i]);
312 fprintf(fp,"\tr%d[shape=box,label=\"%s\"]\n",i,relname);
313 ASC_FREE(relname);
314 }
315 }
316
317 /* and the vars */
318 nsv = slv_get_num_solvers_vars(sys);
319 nv = slv_count_solvers_vars(sys,vfilter);
320 svars = slv_get_solvers_var_list(sys);
321 fprintf(fp,"\n\n\t/* %d variables */\n\n",nv);
322 for(j=0; j<nsv; ++j){
323 if(var_apply_filter(svars[j],vfilter)){
324 varname = var_make_name(sys,svars[j]);
325 if(var_fixed(svars[j])){
326 fprintf(fp,"s\tv%d[label=\"%s\",style=filled,color=green]\n",j,varname);
327 }else{
328 fprintf(fp,"\tv%d[label=\"%s\"]\n",j,varname);
329 }
330 ASC_FREE(varname);
331 }
332 }
333
334 /* now output the edges between them */
335 fprintf(fp,"\n\n\t/* incidences */\n\n");
336 for(i=0; i<nsr; ++i){
337 if(!rel_apply_filter(srels[i],rfilter))continue;
338
339 ivars = rel_incidence_list(srels[i]);
340 niv = rel_n_incidences(srels[i]);
341
342 for(j=0; j<niv; ++j){
343 if(!var_apply_filter(ivars[j],vfilter))continue;
344 if(j==i){
345 fprintf(fp,"\tr%d->v%d\n",i,var_sindex(ivars[j]));
346 }else{
347 fprintf(fp,"\tv%d->r%d\n",var_sindex(ivars[j]),i);
348 }
349 }
350 }
351
352 fprintf(fp,"}\n");
353 #endif
354 CONSOLE_DEBUG("Completed graph output");
355 return 0;
356 }
357
358
359
360

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22