source: proiecte/NBody/Tree codes/treeio.c @ 170

Last change on this file since 170 was 170, checked in by (none), 14 years ago
File size: 17.5 KB
Line 
1/****************************************************************************/
2/* TREEIO.C: I/O routines for hierarchical N-body code. Public routines:    */
3/* inputdata(), startoutput(), output(), savestate(), restorestate().       */
4/* Copyright (c) 2001 by Joshua E. Barnes, Honolulu, Hawai`i.               */
5/****************************************************************************/
6
7#include "stdinc.h"
8#include "mathfns.h"
9#include "vectmath.h"
10#include "getparam.h"
11#include "treecode.h"
12
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <strings.h>
16
17/*
18 * Prototypes for local routines.
19 */
20
21local void outputdata(void);                    /* write N-body data        */
22local void diagnostics(void);                   /* eval N-body diagnostics  */
23local void in_int(stream, int *);               /* input integer value      */
24local void in_real(stream, real *);             /* input real value         */
25local void in_vector(stream, vector);           /* input vector of reals    */
26local void out_int(stream, int);                /* output integer value     */
27local void out_real(stream, real);              /* output real value        */
28local void out_vector(stream, vector);          /* output vector of reals   */
29
30/*
31 * Diagnositc output variables.
32 */
33
34local real mtot;                                /* total mass of system     */
35local real etot[3];                             /* Etot, KE, PE of system   */
36local matrix keten;                             /* kinetic energy tensor    */
37local matrix peten;                             /* potential energy tensor  */
38local vector cmpos;                             /* center of mass position  */
39local vector cmvel;                             /* center of mass velocity  */
40local vector amvec;                             /* angular momentum vector  */
41
42#define IFMT  "%d "                             /* output format for ints   */
43#define RFMT  "%f "                         /* output format for reals  */
44
45
46/*
47 * INPUTDATA: read initial conditions from input file.
48 */
49
50void inputdata(void)
51{
52    stream instr;
53    int ndim;
54    bodyptr p;
55
56    instr = stropen(infile, "r");               /* open input stream        */
57    in_int(instr, &nbody);                      /* read number of bodies    */
58    if (nbody < 1)
59        error("inputdata: nbody = %d is absurd\n", nbody);
60    in_int(instr, &ndim);                       /* read number of dims      */
61    if (ndim != NDIM)
62        error("inputdata: ndim = %d; expected %d\n", ndim, NDIM);
63    in_real(instr, &tnow);                      /* read starting time       */
64    bodytab = (bodyptr) allocate(nbody * sizeof(body));
65                                                /* allocate body array      */
66    for (p = bodytab; p < bodytab+nbody; p++)   /* loop over all bodies     */
67        in_real(instr, &Mass(p));               /* read mass of each        */
68    for (p = bodytab; p < bodytab+nbody; p++)
69        in_vector(instr, Pos(p));               /* read position of each    */
70    for (p = bodytab; p < bodytab+nbody; p++)
71        in_vector(instr, Vel(p));               /* read velocity of each    */
72    fclose(instr);                              /* close input stream       */
73    if (scanopt(options, "reset-time"))         /* reset starting time?     */
74        tnow = 0.0;                             /* then set it to zero      */
75    for (p = bodytab; p < bodytab+nbody; p++)   /* loop over new bodies     */
76        Type(p) = BODY;                         /* initialize type field    */
77}
78void inputdata_2(void)
79{
80   stream instr;
81    int ndim;
82    bodyptr p;
83   
84   
85    instr = stropen(infile, "r");               /* open input stream        */
86    in_int(instr, &nbody);                      /* read number of bodies    */
87    if (nbody < 1)
88        error("inputdata: nbody = %d is absurd\n", nbody);
89    bodytab = (bodyptr) allocate(nbody * sizeof(body));
90                                                /* allocate body array      */
91    in_real(instr, &tnow);
92    for (p = bodytab; p < bodytab+nbody; p++)   /* loop over all bodies     */
93    {
94        in_real(instr, &Mass(p));               /* read mass of each        */ 
95        in_vector(instr, Pos(p));               /* read position of each    */   
96        in_vector(instr, Vel(p));               /* read velocity of each    */ 
97    }
98    fclose(instr);                              /* close input stream       */
99    if (scanopt(options, "reset-time"))         /* reset starting time?     */
100        tnow = 0.0;                             /* then set it to zero      */
101    for (p = bodytab; p < bodytab+nbody; p++)   /* loop over new bodies     */
102        Type(p) = BODY;                         /* initialize type field    */
103}
104/*
105 * STARTOUTPUT: begin output to log file.
106 */
107
108void startoutput(void)
109{
110    printf("\n%s\n", headline);                 /* print headline, params   */
111#if defined(USEFREQ)
112    printf("\n%8s%10s%10s", "nbody", "freq", "eps");
113#else
114    printf("\n%8s%10s%10s", "nbody", "dtime", "eps");
115#endif
116#if !defined(QUICKSCAN)
117    printf("%10s", "theta");
118#endif
119#if defined(USEFREQ)
120    printf("%10s%10s%10s\n", "usequad", "freqout", "tstop");
121    printf("%8d%10.2f%10.4f", nbody, freq, eps);
122#else
123    printf("%10s%10s%10s\n", "usequad", "dtout", "tstop");
124    printf("%8d%10.5f%10.4f", nbody, dtime, eps);
125#endif
126#if !defined(QUICKSCAN)
127    printf("%10.2f", theta);
128#endif
129#if defined(USEFREQ)
130    printf("%10s%10.2f%10.4f\n", usequad ? "true" : "false", freqout, tstop);
131#else
132    printf("%10s%10.5f%10.4f\n", usequad ? "true" : "false", dtout, tstop);
133#endif
134    if (! strnull(options))                     /* print options, if any    */
135        printf("\n\toptions: %s\n", options);
136    if (! strnull(savefile))                    /* was state file given?    */
137        savestate(savefile);                    /* save initial data        */
138}
139
140/*
141 * FORCEREPORT: print staristics on tree construction and force calculation.
142 */
143
144void forcereport(void)
145{
146    printf("\n\t%8s%8s%8s%8s%10s%10s%8s\n",
147           "rsize", "tdepth", "ftree",
148           "actmax", "nbbtot", "nbctot", "CPUfc");
149    printf("\t%8.1f%8d%8.3f%8d%10d%10d%8.3f\n",
150           rsize, tdepth, (nbody + ncell - 1) / ((real) ncell),
151           actmax, nbbcalc, nbccalc, cpuforce);
152}
153
154/*
155 * OUTPUT: compute diagnostics and output body data.
156 */
157
158void output(void)
159{
160    real cmabs, amabs, teff;
161
162    diagnostics();                              /* compute std diagnostics  */
163    ABSV(cmabs, cmvel);                         /* find magnitude of cm vel */
164    ABSV(amabs, amvec);                         /* find magnitude of J vect */
165    printf("\n    %8s%8s%8s%8s%8s%8s%8s%8s\n",
166           "time", "|T+U|", "T", "-U", "-T/U", "|Vcom|", "|Jtot|", "CPUtot");
167    printf("    %8.3f%8.5f%8.5f%8.5f%8.5f%8.5f%8.5f%8.3f\n",
168           tnow, ABS(etot[0]), etot[1], -etot[2], -etot[1]/etot[2],
169           cmabs, amabs, cputime());
170#if defined(USEFREQ)
171    teff = tnow + (freq > 0 ? 0.125/freq : 0);  /* anticipate slightly...   */
172#else
173    teff = tnow + dtime/8;                      /* anticipate slightly...   */
174#endif
175    if (! strnull(outfile) && teff >= tout)     /* time for data output?    */
176        //outputdata();
177        {}
178    if (! strnull(savefile))                    /* was state file given?    */
179        savestate(savefile);                    /* save data for restart    */
180}
181
182/*
183 * OUTPUTDATA: output body data.
184 */
185
186/*void outputdata(void)
187{
188    char namebuf[256];
189    struct stat buf;
190    stream outstr;
191    bodyptr p;
192
193    sprintf(namebuf, outfile, nstep);           // construct output name   
194    if (stat(namebuf, &buf) != 0)               // no output file exists?   
195        outstr = stropen(namebuf, "w");         // create & open for output
196    else                                        // else file already exists
197        outstr = stropen(namebuf, "a");         // reopen and append output
198    out_int(outstr, nbody);                     // write number of bodies   
199    out_int(outstr, NDIM);                      // number of dimensions     
200    out_real(outstr, tnow);                     // and current time value   
201    for (p = bodytab; p < bodytab+nbody; p++)   // loop over all bodies     
202        out_real(outstr, Mass(p));              // output mass of each     
203    for (p = bodytab; p < bodytab+nbody; p++)
204        out_vector(outstr, Pos(p));             // output positions         
205    for (p = bodytab; p < bodytab+nbody; p++)
206        out_vector(outstr, Vel(p));             // output velocities       
207    if (scanopt(options, "out-phi"))            // potentials requested?   
208        for (p = bodytab; p < bodytab+nbody; p++)
209            out_real(outstr, Phi(p));           // output potentials       
210    if (scanopt(options, "out-acc"))            // accelerations requested?
211        for (p = bodytab; p < bodytab+nbody; p++)
212            out_vector(outstr, Acc(p));         // output accelerations     
213    fclose(outstr);                             // close up output file     
214    printf("\n\tdata output to file %s at time %f\n", namebuf, tnow);
215#if defined(USEFREQ)
216    tout += 1.0 / freqout;                      // schedule next output     
217#else
218    tout += dtout;                              // schedule next output     
219#endif
220}
221*/
222
223void outputdata(void)
224{
225    char namebuf[256];
226    struct stat buf;
227    stream outstr;
228    bodyptr p;
229    int tnow_int;
230
231    sprintf(namebuf, outfile, nstep);           // construct output name   
232    if (stat(namebuf, &buf) != 0)               // no output file exists?   
233        outstr = stropen(namebuf, "w");         // create & open for output
234    else                                        // else file already exists
235        outstr = stropen(namebuf, "a");         // reopen and append output
236    tnow_int = tnow;
237    out_int(outstr, nbody);                     // write number of bodies         
238    out_real(outstr, tnow);                       
239    //out_int(outstr, tnow_int);                        // and current time value
240    for (p = bodytab; p < bodytab+nbody; p++)   // loop over all bodies     
241    {
242      //out_real(outstr, Mass(p));              // output mass of each   
243      fprintf(outstr, RFMT, Mass(p));
244      out_vector(outstr, Pos(p));             // output positions
245      out_vector(outstr, Vel(p));             // output velocities
246      fprintf(outstr,"\n");
247    } 
248    //fprintf(outstr,"\n");
249    fclose(outstr);                             // close up output file     
250    printf("\n\tdata output to file %s at time %f\n", namebuf, tnow);
251#if defined(USEFREQ)
252    tout += 1.0 / freqout;                      // schedule next output     
253#else
254    tout += dtout;                              // schedule next output     
255#endif
256}
257
258/*
259 * DIAGNOSTICS: compute set of dynamical diagnostics.
260 */
261
262local void diagnostics(void)
263{
264    register bodyptr p;
265    real velsq;
266    vector tmpv;
267    matrix tmpt;
268
269    mtot = 0.0;                                 /* zero total mass          */
270    etot[1] = etot[2] = 0.0;                    /* zero total KE and PE     */
271    CLRM(keten);                                /* zero ke tensor           */
272    CLRM(peten);                                /* zero pe tensor           */
273    CLRV(amvec);                                /* zero am vector           */
274    CLRV(cmpos);                                /* zero c. of m. position   */
275    CLRV(cmvel);                                /* zero c. of m. velocity   */
276    for (p = bodytab; p < bodytab+nbody; p++) { /* loop over all particles  */
277        mtot += Mass(p);                        /* sum particle masses      */
278        DOTVP(velsq, Vel(p), Vel(p));           /* square vel vector        */
279        etot[1] += 0.5 * Mass(p) * velsq;       /* sum current KE           */
280        etot[2] += 0.5 * Mass(p) * Phi(p);      /* and current PE           */
281        MULVS(tmpv, Vel(p), 0.5 * Mass(p));     /* sum 0.5 m v_i v_j        */
282        OUTVP(tmpt, tmpv, Vel(p));
283        ADDM(keten, keten, tmpt);
284        MULVS(tmpv, Pos(p), Mass(p));           /* sum m r_i a_j            */
285        OUTVP(tmpt, tmpv, Acc(p));
286        ADDM(peten, peten, tmpt);
287        CROSSVP(tmpv, Vel(p), Pos(p));          /* sum angular momentum     */
288        MULVS(tmpv, tmpv, Mass(p));
289        ADDV(amvec, amvec, tmpv);
290        MULVS(tmpv, Pos(p), Mass(p));           /* sum cm position          */
291        ADDV(cmpos, cmpos, tmpv);
292        MULVS(tmpv, Vel(p), Mass(p));           /* sum cm momentum          */
293        ADDV(cmvel, cmvel, tmpv);
294    }
295    etot[0] = etot[1] + etot[2];                /* sum KE and PE            */
296    DIVVS(cmpos, cmpos, mtot);                  /* normalize cm coords      */
297    DIVVS(cmvel, cmvel, mtot);
298}
299
300/*
301 * IN_INT, IN_REAL, IN_VECTOR: low level input routines.
302 */
303
304local void in_int(stream str, int *iptr)
305{
306#if !defined(BINARYIO)
307    if (fscanf(str, "%d", iptr) != 1)
308        error("in_int: input conversion error\n");
309#else
310    if (fread((void *) iptr, sizeof(int), 1, str) != 1)
311        error("in_int: fread failed\n");
312#endif
313}
314
315local void in_real(stream str, real *rptr)
316{
317    double tmp;
318
319#if !defined(BINARYIO)
320    if (fscanf(str, "%lf", &tmp) != 1)
321        error("in_real: input conversion error\n");
322    *rptr = tmp;
323#else
324    if (fread((void *) rptr, sizeof(real), 1, str) != 1)
325        error("in_real: fread failed\n");
326#endif
327}
328
329local void in_vector(stream str, vector vec)
330{
331    double tmpx, tmpy, tmpz;
332
333#if !defined(BINARYIO)
334    if (fscanf(str, "%lf%lf%lf", &tmpx, &tmpy, &tmpz) != 3)
335        error("in_vector: input conversion error\n");
336    vec[0] = tmpx;
337    vec[1] = tmpy;
338    vec[2] = tmpz;
339#else
340    if (fread((void *) vec, sizeof(real), NDIM, str) != NDIM)
341        error("in_vector: fread failed\n");
342#endif
343}
344
345/*
346 * OUT_INT, OUT_REAL, OUT_VECTOR: low level output routines. */
347
348
349local void out_int(stream str, int ival)
350{
351#if !defined(BINARYIO)
352    if (fprintf(str, IFMT "\n", ival) < 0)
353        error("out_int: fprintf failed\n");
354#else
355    if (fwrite((void *) &ival, sizeof(int), 1, str) != 1)
356        error("out_int: fwrite failed\n");
357#endif
358}
359
360local void out_real(stream str, real rval)
361{
362#if !defined(BINARYIO)
363    if (fprintf(str, RFMT "\n", rval) < 0)
364        error("out_real: fprintf failed\n");
365#else
366    if (fwrite((void *) &rval, sizeof(real), 1, str) != 1)
367        error("out_real: fwrite failed\n");
368#endif
369}
370
371local void out_vector(stream str, vector vec)
372{
373#if !defined(BINARYIO)
374    if (fprintf(str, RFMT RFMT RFMT, vec[0], vec[1], vec[2]) < 0)
375        error("out_vector: fprintf failed\n");
376#else
377    if (fwrite((void *) vec, sizeof(real), NDIM, str) != NDIM)
378        error("out_vector: fwrite failed\n");
379#endif
380}
381
382/*
383 * SAVESTATE: write current state to disk file.
384 */
385
386#define safewrite(ptr,len,str)                  \
387    if (fwrite((void *) ptr, len, 1, str) != 1) \
388        error("savestate: fwrite failed\n")
389
390void savestate(string pattern)
391{
392    char namebuf[256];
393    stream str;
394    int nchars;
395
396    sprintf(namebuf, pattern, nstep & 1);       /* construct alternate name */
397    str = stropen(namebuf, "w!");
398    nchars = strlen(getargv0()) + 1;
399    safewrite(&nchars, sizeof(int), str);
400    safewrite(getargv0(), nchars * sizeof(char), str);
401    nchars = strlen(getversion()) + 1;
402    safewrite(&nchars, sizeof(int), str);
403    safewrite(getversion(), nchars * sizeof(char), str);
404#if defined(USEFREQ)
405    safewrite(&freq, sizeof(real), str);
406#else
407    safewrite(&dtime, sizeof(real), str);
408#endif
409#if !defined(QUICKSCAN)
410    safewrite(&theta, sizeof(real), str);
411#endif
412    safewrite(&usequad, sizeof(bool), str);
413    safewrite(&eps, sizeof(real), str);
414    nchars = strlen(options) + 1;
415    safewrite(&nchars, sizeof(int), str);
416    safewrite(options, nchars * sizeof(char), str);
417    safewrite(&tstop, sizeof(real), str);
418#if defined(USEFREQ)
419    safewrite(&freqout, sizeof(real), str);
420#else
421    safewrite(&dtout, sizeof(real), str);
422#endif
423    safewrite(&tnow, sizeof(real), str);
424    safewrite(&tout, sizeof(real), str);
425    safewrite(&nstep, sizeof(int), str);
426    safewrite(&rsize, sizeof(real), str);
427    safewrite(&nbody, sizeof(int), str);
428    safewrite(bodytab, nbody * sizeof(body), str);
429    fclose(str);
430}
431
432/*
433 * RESTORESTATE: restore state from disk file.
434 */
435
436#define saferead(ptr,len,str)                  \
437    if (fread((void *) ptr, len, 1, str) != 1) \
438        error("restorestate: fread failed\n")
439
440void restorestate(string file)
441{
442    stream str;
443    int nchars;
444    string program, version;
445
446    str = stropen(file, "r");
447    saferead(&nchars, sizeof(int), str);
448    program = (string) allocate(nchars * sizeof(char));
449    saferead(program, nchars * sizeof(char), str);
450    saferead(&nchars, sizeof(int), str);
451    version = (string) allocate(nchars * sizeof(char));
452    saferead(version, nchars * sizeof(char), str);
453    if (! streq(program, getargv0()) ||         /* check program, version   */
454          ! streq(version, getversion()))
455        printf("warning: state file may be outdated\n\n");
456#if defined(USEFREQ)
457    saferead(&freq, sizeof(real), str);
458#else
459    saferead(&dtime, sizeof(real), str);
460#endif
461#if !defined(QUICKSCAN)
462    saferead(&theta, sizeof(real), str);
463#endif
464    saferead(&usequad, sizeof(bool), str);
465    saferead(&eps, sizeof(real), str);
466    saferead(&nchars, sizeof(int), str);
467    options = (string) allocate(nchars * sizeof(char));
468    saferead(options, nchars * sizeof(char), str);
469    saferead(&tstop, sizeof(real), str);
470#if defined(USEFREQ)
471    saferead(&freqout, sizeof(real), str);
472#else
473    saferead(&dtout, sizeof(real), str);
474#endif
475    saferead(&tnow, sizeof(real), str);
476    saferead(&tout, sizeof(real), str);
477    saferead(&nstep, sizeof(int), str);
478    saferead(&rsize, sizeof(real), str);
479    saferead(&nbody, sizeof(int), str);
480    bodytab = (bodyptr) allocate(nbody * sizeof(body));
481    saferead(bodytab, nbody * sizeof(body), str);
482    fclose(str);
483}
Note: See TracBrowser for help on using the repository browser.