/*************************************************************************/ /* */ /* Copyright (c) 1994 Stanford University */ /* */ /* All rights reserved. */ /* */ /* Permission is given to use, copy, and modify this software for any */ /* non-commercial purpose as long as this copyright notice is not */ /* removed. All other uses, including redistribution in whole or in */ /* part, are forbidden without prior written permission. */ /* */ /* This software is provided with absolutely no warranty and no */ /* support. */ /* */ /*************************************************************************/ /* * CODE_IO.C: */ EXTERN_ENV #define global extern #include "stdinc.h" /* * INPUTDATA: read initial conditions from input file. */ void inputdata () { stream instr; permanent char headbuf[128]; long ndim; real tnow; bodyptr p; long i; fprintf(stderr,"reading input file : %s\n",infile); fflush(stderr); instr = fopen(infile, "r"); if (instr == NULL) error("inputdata: cannot find file %s\n", infile); sprintf(headbuf, "Hack code: input file %s\n", infile); headline = headbuf; in_int(instr, &nbody); if (nbody < 1) error("inputdata: nbody = %ld is absurd\n", nbody); in_int(instr, &ndim); if (ndim != NDIM) error("inputdata: NDIM = %ld ndim = %ld is absurd\n", NDIM, ndim); in_real(instr, &tnow); for (i = 0; i < MAX_PROC; i++) { Local[i].tnow = tnow; } bodytab = (bodyptr) G_MALLOC(nbody * sizeof(body)); if (bodytab == NULL) error("inputdata: not enuf memory\n"); for (p = bodytab; p < bodytab+nbody; p++) { Type(p) = BODY; Cost(p) = 1; Phi(p) = 0.0; CLRV(Acc(p)); } for (p = bodytab; p < bodytab+nbody; p++) in_real(instr, &Mass(p)); for (p = bodytab; p < bodytab+nbody; p++) in_vector(instr, Pos(p)); for (p = bodytab; p < bodytab+nbody; p++) in_vector(instr, Vel(p)); fclose(instr); } /* * INITOUTPUT: initialize output routines. */ void initoutput() { printf("\n\t\t%s\n\n", headline); printf("%10s%10s%10s%10s%10s%10s%10s%10s\n", "nbody", "dtime", "eps", "tol", "dtout", "tstop","fcells","NPROC"); printf("%10ld%10.5f%10.4f%10.2f%10.3f%10.3f%10.2f%10ld\n\n", nbody, dtime, eps, tol, dtout, tstop, fcells, NPROC); } /* * STOPOUTPUT: finish up after a run. */ /* * OUTPUT: compute diagnostics and output data. */ void output(long ProcessId) { long nttot, nbavg, ncavg,k; vector tempv1,tempv2; if ((Local[ProcessId].tout - 0.01 * dtime) <= Local[ProcessId].tnow) { Local[ProcessId].tout += dtout; } diagnostics(ProcessId); if (Local[ProcessId].mymtot!=0) { LOCK(Global->CountLock); Global->n2bcalc += Local[ProcessId].myn2bcalc; Global->nbccalc += Local[ProcessId].mynbccalc; Global->selfint += Local[ProcessId].myselfint; ADDM(Global->keten, Global-> keten, Local[ProcessId].myketen); ADDM(Global->peten, Global-> peten, Local[ProcessId].mypeten); for (k=0;k<3;k++) Global->etot[k] += Local[ProcessId].myetot[k]; ADDV(Global->amvec, Global-> amvec, Local[ProcessId].myamvec); MULVS(tempv1, Global->cmphase[0],Global->mtot); MULVS(tempv2, Local[ProcessId].mycmphase[0], Local[ProcessId].mymtot); ADDV(tempv1, tempv1, tempv2); DIVVS(Global->cmphase[0], tempv1, Global->mtot+Local[ProcessId].mymtot); MULVS(tempv1, Global->cmphase[1],Global->mtot); MULVS(tempv2, Local[ProcessId].mycmphase[1], Local[ProcessId].mymtot); ADDV(tempv1, tempv1, tempv2); DIVVS(Global->cmphase[1], tempv1, Global->mtot+Local[ProcessId].mymtot); Global->mtot +=Local[ProcessId].mymtot; UNLOCK(Global->CountLock); } BARRIER(Global->Barrier,NPROC); if (ProcessId==0) { nttot = Global->n2bcalc + Global->nbccalc; nbavg = (long) ((real) Global->n2bcalc / (real) nbody); ncavg = (long) ((real) Global->nbccalc / (real) nbody); } } /* * DIAGNOSTICS: compute set of dynamical diagnostics. */ void diagnostics(long ProcessId) { register bodyptr p,*pp; real velsq; vector tmpv; matrix tmpt; Local[ProcessId].mymtot = 0.0; Local[ProcessId].myetot[1] = Local[ProcessId].myetot[2] = 0.0; CLRM(Local[ProcessId].myketen); CLRM(Local[ProcessId].mypeten); CLRV(Local[ProcessId].mycmphase[0]); CLRV(Local[ProcessId].mycmphase[1]); CLRV(Local[ProcessId].myamvec); for (pp = Local[ProcessId].mybodytab+Local[ProcessId].mynbody -1; pp >= Local[ProcessId].mybodytab; pp--) { p= *pp; Local[ProcessId].mymtot += Mass(p); DOTVP(velsq, Vel(p), Vel(p)); Local[ProcessId].myetot[1] += 0.5 * Mass(p) * velsq; Local[ProcessId].myetot[2] += 0.5 * Mass(p) * Phi(p); MULVS(tmpv, Vel(p), 0.5 * Mass(p)); OUTVP(tmpt, tmpv, Vel(p)); ADDM(Local[ProcessId].myketen, Local[ProcessId].myketen, tmpt); MULVS(tmpv, Pos(p), Mass(p)); OUTVP(tmpt, tmpv, Acc(p)); ADDM(Local[ProcessId].mypeten, Local[ProcessId].mypeten, tmpt); MULVS(tmpv, Pos(p), Mass(p)); ADDV(Local[ProcessId].mycmphase[0], Local[ProcessId].mycmphase[0], tmpv); MULVS(tmpv, Vel(p), Mass(p)); ADDV(Local[ProcessId].mycmphase[1], Local[ProcessId].mycmphase[1], tmpv); CROSSVP(tmpv, Pos(p), Vel(p)); MULVS(tmpv, tmpv, Mass(p)); ADDV(Local[ProcessId].myamvec, Local[ProcessId].myamvec, tmpv); } Local[ProcessId].myetot[0] = Local[ProcessId].myetot[1] + Local[ProcessId].myetot[2]; if (Local[ProcessId].mymtot!=0){ DIVVS(Local[ProcessId].mycmphase[0], Local[ProcessId].mycmphase[0], Local[ProcessId].mymtot); DIVVS(Local[ProcessId].mycmphase[1], Local[ProcessId].mycmphase[1], Local[ProcessId].mymtot); } } /* * Low-level input and output operations. */ void in_int(stream str, long *iptr) { if (fscanf(str, "%ld", iptr) != 1) error("in_int: input conversion print_error\n"); } void in_real(stream str, real *rptr) { double tmp; if (fscanf(str, "%lf", &tmp) != 1) error("in_real: input conversion print_error\n"); *rptr = tmp; } void in_vector(stream str, vector vec) { double tmpx, tmpy, tmpz; if (fscanf(str, "%lf%lf%lf", &tmpx, &tmpy, &tmpz) != 3) error("in_vector: input conversion print_error\n"); vec[0] = tmpx; vec[1] = tmpy; vec[2] = tmpz; } void out_int(stream str, long ival) { fprintf(str, " %ld\n", ival); } void out_real(stream str, real rval) { fprintf(str, " %21.14E\n", rval); } void out_vector(stream str, vector vec) { fprintf(str, " %21.14E %21.14E", vec[0], vec[1]); fprintf(str, " %21.14E\n",vec[2]); }