Re-organize BlueGene toolchain files
[gromacs.git] / src / ngmx / g_highway.c
blob1bcbcaec502f251be20e2e8fc1950ed161a057e5
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team,
6 * check out http://www.gromacs.org for more information.
7 * Copyright (c) 2012, by the GROMACS development team, led by
8 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
9 * others, as listed in the AUTHORS file in the top-level source
10 * directory and at http://www.gromacs.org.
12 * GROMACS is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2.1
15 * of the License, or (at your option) any later version.
17 * GROMACS is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with GROMACS; if not, see
24 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * If you want to redistribute modifications to GROMACS, please
28 * consider that scientific software is very special. Version
29 * control is crucial - bugs must be traceable. We will be happy to
30 * consider code for inclusion in the official distribution, but
31 * derived work must not be called official GROMACS. Details are found
32 * in the README & COPYING files - if they are missing, get the
33 * official version at http://www.gromacs.org.
35 * To help us fund GROMACS development, we humbly ask that you cite
36 * the research papers on the package. Check out http://www.gromacs.org.
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
42 #include <stdio.h>
43 #include <string.h>
44 #include <math.h>
45 #include "futil.h"
46 #include "macros.h"
47 #include "smalloc.h"
48 #include "xutil.h"
49 #include "copyrite.h"
50 #include "statutil.h"
51 #include "gmx_fatal.h"
53 /* Units are meter and second */
55 typedef struct {
56 int id; /* Identification */
57 float x,xold;
58 float v; /* Position and velocity */
59 float vwanted; /* Wants to drive at this speed */
60 float acc; /* Acceleration */
61 float brake; /* Break */
62 int lane,oldlane; /* Currently in lane */
63 gmx_bool bBrake; /* Currently on the brakes */
64 unsigned long col; /* Colour */
65 unsigned long roof; /* Roof Colour */
66 } t_car;
68 typedef struct {
69 int nlane; /* Number of lanes on highway */
70 int metres; /* Road length */
71 float dt; /* Time step */
72 float min_dist; /* Min distance cars can come */
73 int sleep; /* How long to sleep in between updates */
74 } t_input;
76 static const char *Driving[] = { "Start","Stop" };
77 static const char *Fogs[] = { "Fog", "No Fog" };
78 enum buttons { Quit, StartStop, Fog, NBUT };
79 static const char *but_name[NBUT] = { "Quit", "Start", "Fog" };
81 typedef struct {
82 int ncars;
83 t_car *cars;
84 t_input ir;
85 int step;
86 gmx_bool bDriving; /* Are we driving ? */
87 gmx_bool bFog; /* Is it foggy ? */
88 t_windata main;
89 t_windata win;
90 t_windata but[NBUT];
91 } t_xhighway;
93 int read_input(t_x11 *x11,const char *fn,t_car **cars,t_input *ir)
95 FILE *in;
96 int i,n;
97 char buf[100],b2[100];
98 t_car *c;
100 in=ffopen(fn,"r");
101 if (fscanf(in,"%d %d %f %f %d",
102 &ir->nlane,&ir->metres,&ir->dt,&ir->min_dist,&ir->sleep) != 5)
103 gmx_fatal(FARGS,"Not enough parameters in %s line 1",fn);
104 if (fscanf(in,"%d",&n) != 1)
105 gmx_fatal(FARGS,"Not enough parameters in %s line 2",fn);
106 snew(*cars,n);
108 for(i=0; (i<n); i++) {
109 c=&((*cars)[i]);
110 c->id=i;
111 c->lane=0;
112 if (fscanf(in,"%f %f %f %f %f %s %s",&(c->x),&(c->v),&(c->vwanted),
113 &(c->acc),&(c->brake),buf,b2) != 7)
114 gmx_fatal(FARGS,"Not enough parameters in %s line %d",fn,3+i);
115 x11->GetNamedColor(x11,buf,&(c->col));
116 x11->GetNamedColor(x11,b2,&(c->roof));
118 ffclose(in);
120 return n;
123 static float get_dist(int ncars,t_car cars[],int which,gmx_bool bFog,
124 int dir,int lane,int metres,int *nearest)
126 int i,near;
127 float dist,nd;
129 if (dir < 0)
130 dist=-metres;
131 else
132 dist=metres;
133 near=-1;
135 for(i=0; (i<ncars); i++)
136 if ((i != which) && (cars[i].oldlane == lane)){
137 nd=cars[i].xold-cars[which].xold;
138 if ((nd < 0) && (dir > 0))
139 nd+=metres;
140 else if ((nd > 0) && (dir < 0))
141 nd-=metres;
143 if (!bFog || (fabs(nd) < 50)) {
144 if (dir < 0) {
145 if (nd > dist) {
146 dist=nd;
147 near=i;
150 else if (dir > 0) {
151 if (nd < dist) {
152 dist=nd;
153 near=i;
158 *nearest=near;
159 return fabs(dist);
162 void simulate(t_x11 *x11,t_xhighway *xhw,
163 int ncars,t_car cars[],t_input *ir)
165 int i,n_bef,n_bef1,n_beh;
166 float dist,distf,distb;
168 for(i=0; (i<ncars); i++) {
169 cars[i].xold=cars[i].x;
170 cars[i].oldlane=cars[i].lane;
172 for(i=0; (i<ncars); i++) {
173 cars[i].bBrake=FALSE;
174 dist=get_dist(ncars,cars,i,xhw->bFog,
175 1,cars[i].lane,ir->metres,&n_bef);
176 if (dist < ir->min_dist) {
177 distf=get_dist(ncars,cars,i,xhw->bFog,
178 1,cars[i].lane+1,ir->metres,&n_bef1);
179 distb=get_dist(ncars,cars,i,xhw->bFog,
180 -1,cars[i].lane+1,ir->metres,&n_beh);
181 if ((cars[i].lane < ir->nlane-1) && (distb >= ir->min_dist) &&
182 (distf >= ir->min_dist))
183 cars[i].lane += 1;
184 else {
185 /* Use brakes */
186 cars[i].v -= cars[i].brake*ir->dt;
187 if (cars[i].v < 0)
188 cars[i].v = 0;
189 if (n_bef != -1)
190 if ((cars[i].v < cars[n_bef].v) && (dist > ir->min_dist/2))
191 cars[i].v=cars[n_bef].v;
192 cars[i].bBrake=TRUE;
195 else if ((cars[i].lane > 0) && (cars[i].v == cars[i].vwanted)) {
196 /* Check if I can go right again */
197 dist=get_dist(ncars,cars,i,xhw->bFog,
198 1,cars[i].lane-1,ir->metres,&n_bef);
199 distb=get_dist(ncars,cars,i,xhw->bFog,
200 -1,cars[i].lane-1,ir->metres,&n_beh);
201 if ((dist >= ir->min_dist) && (distb >= ir->min_dist))
202 cars[i].lane -= 1;
205 cars[i].x += cars[i].v*ir->dt;
206 if (cars[i].x > ir->metres)
207 cars[i].x -= ir->metres;
208 if (!cars[i].bBrake && (cars[i].v < cars[i].vwanted)) {
209 cars[i].v += cars[i].acc*ir->dt;
210 if (cars[i].v > cars[i].vwanted)
211 cars[i].v = cars[i].vwanted;
214 /* Detect Crashes */
215 /* Plot */
216 usleep(xhw->ir.sleep);
217 ExposeWin(x11->disp,xhw->win.self);
220 static void Configure(t_xhighway *xhw)
222 Window self;
223 int i,h,w,dh;
224 float dw;
226 dh=20;
227 h=xhw->main.height;
228 w=xhw->main.width;
229 dw=((float)(w-2))/NBUT-4;
230 for(i=0; (i<NBUT); i++) {
231 t_windata *wd=&(xhw->but[i]);
233 self=wd->self;
234 InitWin(wd,2+i*(dw+4),2,dw,dh,1,but_name[i]);
235 wd->self=self;
237 self=xhw->win.self;
238 InitWin(&xhw->win,2,dh+6,w-6,h-dh-10,1,xhw->main.text);
239 xhw->win.self=self;
242 static void draw_car(Display *disp,Window wd,GC gc,
243 t_car *car,int w0,int h0)
245 const int w=30;
246 const int h=14;
247 const int wr=10;
248 const int hr=8;
249 int j,w1,h1;
250 int jmax,hmax;
252 w1=w0-w / 2;
253 h1=h0-h / 2;
255 /* Carosserie */
256 XSetForeground(disp,gc,car->col);
257 XFillRectangle(disp,wd,gc,w1,h1,w,h);
259 /* Dak */
260 XSetForeground(disp,gc,car->roof);
261 XFillRectangle(disp,wd,gc,w0-wr/2,h0-hr/2,wr,hr);
263 /* Achterlicht */
264 if (car->bBrake) {
265 XSetForeground(disp,gc,YELLOW);
266 jmax=5;
267 hmax=5;
269 else {
270 XSetForeground(disp,gc,LIGHTRED);
271 jmax=3;
272 hmax=3;
274 for(j=1; (j<jmax); j++) {
275 int w11=w1-1-j;
276 int h11=h1-1;
277 XDrawLine(disp,wd,gc,w11,h11, w11,h11+hmax);
278 XDrawLine(disp,wd,gc,w11,h11+h-hmax,w11,h11+h);
281 /* Voorlicht */
282 XSetForeground(disp,gc,WHITE);
283 for(j=1; (j<3); j++) {
284 int w11=w1+w+j;
285 int h11=h1-1;
286 XDrawLine(disp,wd,gc,w11,h11, w11,h11+3);
287 XDrawLine(disp,wd,gc,w11,h11+h-3,w11,h11+h);
291 static gmx_bool xhwCallBack(struct t_x11 *x11,XEvent *event, Window wd, void *data)
293 t_xhighway *xhw;
294 t_windata *win;
295 float sx;
296 int i;
297 static int nyy=0;
298 static int *yy;
300 xhw = (t_xhighway *)data;
301 win = &(xhw->win);
303 if (nyy == 0) {
304 nyy=2*xhw->ir.nlane+1;
305 snew(yy,nyy);
307 for(i=0; (i<nyy); i++)
308 yy[i]=((float) i*win->height)/(nyy-1);
310 switch (event->type) {
311 case Expose: {
312 if (wd == win->self) {
313 sx=(float)win->width / xhw->ir.metres;
315 XClearWindow(x11->disp,win->self);
316 XSetForeground(x11->disp,x11->gc,WHITE);
318 for(i=2; (i<nyy-1); i+=2)
319 XDrawLine(x11->disp,win->self,x11->gc,0,yy[i],win->width-1,yy[i]);
321 for(i=0; (i<xhw->ncars); i++) {
322 t_car *car=&(xhw->cars[i]);
323 int w1=car->x*sx;
324 int h1=yy[1+2*(xhw->ir.nlane-1-car->lane)];
326 draw_car(x11->disp,win->self,x11->gc,car,w1,h1);
328 if (xhw->bDriving)
329 simulate(x11,xhw,xhw->ncars,xhw->cars,&xhw->ir);
331 break;
333 case ConfigureNotify:
334 if (wd == xhw->main.self) {
335 xhw->main.width=event->xconfigure.width;
336 xhw->main.height=event->xconfigure.height;
337 Configure(xhw);
338 for(i=0; (i<NBUT); i++)
339 XMoveResizeWindow(x11->disp,xhw->but[i].self,
340 xhw->but[i].x,xhw->but[i].y,
341 xhw->but[i].width,xhw->but[i].height);
342 XMoveResizeWindow(x11->disp,win->self,
343 win->x,win->y,win->width,win->height);
345 else if (wd == win->self) {
346 win->width=event->xconfigure.width;
347 win->height=event->xconfigure.height;
349 break;
350 case ButtonPress:
351 return TRUE;
352 default:
353 break;
355 return FALSE;
358 static gmx_bool butCallBack(struct t_x11 *x11,XEvent *event, Window wd, void *data)
360 XSetWindowAttributes attr;
361 t_xhighway *xhw;
362 t_windata *win;
363 const char *label;
364 int i;
366 xhw = (t_xhighway *)data;
367 for(i=0; (i<NBUT); i++) {
368 if (xhw->but[i].self == wd)
369 break;
371 if (i == NBUT) {
372 fprintf(stderr,"Incorrect window: %x in butcallback\n",(unsigned)wd);
373 return FALSE;
375 win=&(xhw->but[i]);
377 switch (event->type) {
378 case Expose:
379 XClearWindow(x11->disp,win->self);
380 switch (i) {
381 case StartStop:
382 label=Driving[xhw->bDriving];
383 break;
384 case Fog:
385 label=Fogs[xhw->bFog];
386 break;
387 default:
388 label=win->text;
390 XSetForeground(x11->disp,x11->gc,WHITE);
391 TextInWin(x11,win,label,eXCenter,eYCenter);
392 break;
394 case ConfigureNotify:
395 win->width=event->xconfigure.width;
396 win->height=event->xconfigure.height;
397 break;
398 case ButtonPress:
399 switch (i) {
400 case Quit:
401 return TRUE;
402 case StartStop:
403 xhw->bDriving=1-xhw->bDriving;
404 ExposeWin(x11->disp,win->self);
405 if (xhw->bDriving)
406 ExposeWin(x11->disp,xhw->win.self);
407 break;
408 case Fog:
409 xhw->bFog=1-xhw->bFog;
410 if (xhw->bFog)
411 attr.background_pixel=DARKGREY;
412 else
413 attr.background_pixel=BLACK;
414 XChangeWindowAttributes(x11->disp,xhw->win.self,CWBackPixel,&attr);
415 /*ExposeWin(x11->disp,win->self);*/
416 break;
417 default:
418 break;
420 break;
421 default:
422 break;
424 return FALSE;
427 t_xhighway *GetXHW(t_x11 *x11,const char *infile)
429 t_xhighway *xhw;
430 int i,h,dh,w;
431 char progname[STRLEN];
433 snew(xhw,1);
434 xhw->ncars=read_input(x11,infile,&(xhw->cars),&xhw->ir);
436 h=xhw->ir.nlane*40;
437 dh=20;
438 w=752;
439 strncpy(progname,Program(),STRLEN-1);
440 InitWin(&xhw->main,0,0,w,h+dh+7,1,progname);
441 xhw->main.self=XCreateSimpleWindow(x11->disp,x11->root,
442 xhw->main.x,xhw->main.y,
443 xhw->main.width,xhw->main.height,
444 xhw->main.bwidth,WHITE,BLACK);
445 x11->RegisterCallback(x11,xhw->main.self,0,xhwCallBack,xhw);
446 x11->SetInputMask(x11,xhw->main.self,ButtonPressMask | ExposureMask |
447 StructureNotifyMask);
449 Configure(xhw);
451 for(i=0; (i<NBUT); i++) {
452 t_windata *wd=&(xhw->but[i]);
454 wd->self=XCreateSimpleWindow(x11->disp,xhw->main.self,
455 wd->x,wd->y,
456 wd->width,wd->height,
457 wd->bwidth,WHITE,BLACK);
458 x11->RegisterCallback(x11,wd->self,xhw->main.self,
459 butCallBack,xhw);
460 x11->SetInputMask(x11,wd->self,ButtonPressMask | ExposureMask |
461 StructureNotifyMask);
464 xhw->win.self=XCreateSimpleWindow(x11->disp,xhw->main.self,
465 xhw->win.x,xhw->win.y,
466 xhw->win.width,xhw->win.height,
467 xhw->win.bwidth,WHITE,BLACK);
468 x11->RegisterCallback(x11,xhw->win.self,0,xhwCallBack,xhw);
469 x11->SetInputMask(x11,xhw->win.self,ButtonPressMask | ExposureMask |
470 StructureNotifyMask);
472 return xhw;
475 int main(int argc,char *argv[])
477 const char *desc[] = {
478 "[TT]highway[tt] is the GROMCAS highway simulator. It is an X-windows",
479 "gadget that shows a (periodic) Autobahn with a user defined",
480 "number of cars. Fog can be turned on or off to increase the",
481 "number of crashes. Nice for a background CPU-eater. A sample",
482 "input file is in [TT]$GMXDATA/top/highway.dat[tt]"
484 output_env_t oenv;
485 t_x11 *x11;
486 t_xhighway *xhw;
487 t_filenm fnm[] = {
488 { efDAT, "-f", "highway", ffREAD }
490 #define NFILE asize(fnm)
492 CopyRight(stderr,argv[0]);
493 parse_common_args(&argc,argv,0,NFILE,fnm,
494 0,NULL,asize(desc),desc,0,NULL,&oenv);
496 if ((x11=GetX11(&argc,argv))==NULL) {
497 fprintf(stderr,"Can't connect to X Server.\n"
498 "Check your DISPLAY environment variable\n");
499 exit(1);
501 xhw=GetXHW(x11,opt2fn("-f",NFILE,fnm));
503 XMapWindow(x11->disp,xhw->main.self);
504 XMapSubwindows(x11->disp,xhw->main.self);
505 x11->MainLoop(x11);
506 x11->CleanUp(x11);
508 thanx(stderr);
510 return 0;