Пример #1
0
void reset_vel(PARAMS *p,double f,SSDATA *d)
{
	VECTOR r_hat,vr_vec,t_hat,vt_vec;
	double v,vr,vt;

	/* set speed scaled by desired virial fraction */

	SCALE_VEC(d->vel,sqrt(f));

	/* adjust radial and tangential components as desired */

	if (p->radf < 0) return;

	COPY_VEC(d->pos,r_hat);
	NORM_VEC(r_hat,MAG(r_hat)); /* radial unit vector */

	vr = DOT(d->vel,r_hat);
	COPY_VEC(r_hat,vr_vec);
	SCALE_VEC(vr_vec,vr); /* current radial component of vel */

	SUB_VEC(d->vel,vr_vec,t_hat);
	NORM_VEC(t_hat,MAG(t_hat)); /* tangential unit vector */

	v = MAG(d->vel);
	vr = sqrt(p->radf)*v;
	vt = sqrt(1 - p->radf)*v;

	COPY_VEC(r_hat,vr_vec);
	SCALE_VEC(vr_vec,vr); /* new radial component */

	COPY_VEC(t_hat,vt_vec);
	SCALE_VEC(vt_vec,vt); /* new tangential component */

	ADD_VEC(vr_vec,vt_vec,d->vel);
	}
Пример #2
0
static void
adj_com_vel(SSDATA *d,int n,PROPERTIES *p,VECTOR v)
{
	int i;

	for (i=0;i<n;i++) {
		SUB_VEC(d[i].vel,p->com_vel,d[i].vel);
		ADD_VEC(d[i].vel,v,d[i].vel);
		}
	}
Пример #3
0
static void
adj_com_pos(SSDATA *d,int n,PROPERTIES *p,VECTOR v)
{
	int i;

	for (i=0;i<n;i++) {
		SUB_VEC(d[i].pos,p->com_pos,d[i].pos);
		ADD_VEC(d[i].pos,v,d[i].pos);
		}
	}
Пример #4
0
void MakeBasis(VECTOR v1, VECTOR v2, VECTOR v3)
{
  /*
   * Uses the Gram-Schmidt process to convert the spanning set v1, v2, v3
   * into an orthonormal basis set.
   *
   */

  VECTOR n, v;
  double proj;

  /* Construct first basis vector */

  NORM_VEC(v1, MAG(v1));

  /* Construct second basis vector */

  COPY_VEC(v1, n);
  proj = DOT(v2, n);
  SCALE_VEC(n, proj);
  SUB_VEC(v2, n, v2);
  NORM_VEC(v2, MAG(v2));

  /* Construct third basis vector */

  COPY_VEC(v3, v);
  COPY_VEC(v2, n);
  proj = DOT(v, n);
  SCALE_VEC(n, proj);
  SUB_VEC(v3, n, v3);
  COPY_VEC(v1, n);
  proj = DOT(v, n);
  SCALE_VEC(n, proj);
  SUB_VEC(v3, n, v3);
  NORM_VEC(v3, MAG(v3));
}
Пример #5
0
static void
scale_vel_dsp(SSDATA *d,int n,PROPERTIES *p,VECTOR v)
{
	int i,k;

	for (i=0;i<n;i++) {
		SUB_VEC(d[i].vel,p->com_vel,d[i].vel);
		for (k=0;k<N_DIM;k++)
			d[i].vel[k] *= v[k];
		}

	for (i=0;i<n;i++) {
		ADD_VEC(d[i].vel,p->com_vel,d[i].vel);
		}
	}
Пример #6
0
static void
adj_ang_mom(SSDATA *d,int n,PROPERTIES *p,VECTOR v)
{
	VECTOR u,w;
	int i;

	invert(p->inertia);
	SUB_VEC(v,p->ang_mom,v);
	Transform(p->inertia,v,u);
	SCALE_VEC(u,p->total_mass);
	for (i=0;i<n;i++) {
		CROSS(u,d[i].pos,w);
		ADD_VEC(d[i].vel,w,d[i].vel);
		}
	}
Пример #7
0
/*
  invariant: no sharing between returned term and *any* arguments.
  the caller must free the result.
 */
term* substitute(variable* from, term* to, term* haystack) {
  if (haystack == NULL) return NULL;

  check(from != NULL && to != NULL, "substitute requires non-NULL arguments");
  check(term_locally_well_formed(to), "substitute requires %W to be locally well-formed", to, print_term);
  check(term_locally_well_formed(haystack),"substitute requires %W to be locally well-formed", haystack, print_term);



  switch(haystack->tag) {
  case VAR:
    if (variable_equal(from, haystack->var)) {
      return term_dup(to);
    } else {
      return term_dup(haystack);
    }
  case HOLE:
    return term_dup(haystack);
  case LAM:
    if (variable_equal(from, haystack->var)) {
      return make_lambda(variable_dup(haystack->var),
                         substitute(from, to, haystack->left),
                         term_dup(haystack->right));
    } else {
      if (is_free(haystack->var, to)) {
        variable *g = gensym(haystack->var->name);
        term *tg = make_var(g);
        term* new_haystack = make_lambda(variable_dup(g), term_dup(haystack->left),
                                         substitute(haystack->var, tg, haystack->right));
        free_term(tg);
        term* ans = substitute(from, to, new_haystack);
        free_term(new_haystack);
        return ans;
      }
      return make_lambda(variable_dup(haystack->var),
                         substitute(from, to, haystack->left),
                         substitute(from, to, haystack->right));
    }
  case PI:
    if (variable_equal(from, haystack->var)) {
      return make_pi(variable_dup(haystack->var),
                     substitute(from, to, haystack->left),
                     term_dup(haystack->right));
    } else {
      if (is_free(haystack->var, to)) {
        variable *g = gensym(haystack->var->name);
        term *tg = make_var(g);
        term* new_haystack = make_pi(variable_dup(g), term_dup(haystack->left),
                                     substitute(haystack->var, tg, haystack->right));
        free_term(tg);
        term* ans = substitute(from, to, new_haystack);
        free_term(new_haystack);
        return ans;
      }
      return make_pi(variable_dup(haystack->var),
                     substitute(from, to, haystack->left),
                     substitute(from, to, haystack->right));
    }
  case APP:
    return make_app(substitute(from, to, haystack->left),
                    substitute(from, to, haystack->right));
  case TYPE:
    return term_dup(haystack);
  case DATATYPE:
    {
      term* ans = make_datatype_term(variable_dup(haystack->var),
                                     haystack->num_params, haystack->num_indices);
#define SUB_VEC(dst, src, n) do {                       \
        int __i;                                        \
        for (__i = 0; __i < n; __i++) {                 \
          dst[__i] = substitute(from, to, src[__i]);    \
        }                                               \
      } while(0)

      SUB_VEC(ans->params, haystack->params, haystack->num_params);
      SUB_VEC(ans->indices, haystack->indices, haystack->num_indices);

      return ans;
    }

  case INTRO:
    {
      term* ans = make_intro(variable_dup(haystack->var),
                             substitute(from, to, haystack->left),
                             haystack->num_args,
                             haystack->num_params,
                             haystack->num_indices);

      SUB_VEC(ans->args, haystack->args, haystack->num_args);
      SUB_VEC(ans->params, haystack->params, haystack->num_params);
      SUB_VEC(ans->indices, haystack->indices, haystack->num_indices);
      return ans;
    }
  case ELIM:
    {
      term* ans = make_elim(variable_dup(haystack->var), haystack->num_args, haystack->num_params, haystack->num_indices);

      SUB_VEC(ans->args, haystack->args, haystack->num_args);
      SUB_VEC(ans->params, haystack->params, haystack->num_params);
      SUB_VEC(ans->indices, haystack->indices, haystack->num_indices);

      return ans;
    }
  case IMPLICIT:
    return term_dup(haystack);
  default:
    sentinel("malformed term with tag %d", haystack->tag);
  }

 error:
  return NULL;
}
Пример #8
0
static void
show_encounter(RUBBLE_PILE *rp,int n,BOOLEAN sim_units)
{
	VECTOR rel_pos,rel_vel,ang_mom;
	double m,sr,r,v,eb,a,e,q,Q,vq,vQ;

	assert(n == 2);

	m = rp[0].mass + rp[1].mass;
	sr = rp[0].radius + rp[1].radius;

	SUB_VEC(rp[1].pos,rp[0].pos,rel_pos);
	SUB_VEC(rp[1].vel,rp[0].vel,rel_vel);
	CROSS(rel_pos,rel_vel,ang_mom);

	r = MAG(rel_pos);
	v = MAG(rel_vel);

	if (r == 0) eb = 0;
	else eb = 0.5*SQ(v) - m/r;
	if (eb == 0) {
		a = 0;
		e = 1;
		}
	else {
		a = -0.5*m/eb;
		e = sqrt(1 - MAG_SQ(ang_mom)/(a*m));
		}
	q = (1 - e)*a;
	Q = (1 + e)*a;

	(void) printf("2-body encounter parameters:\n");
	(void) printf("Binding energy per unit reduced mass = %g sim units\n",eb);
	(void) printf("Semi-major axis a = ");
	if (sim_units) (void) printf("%g AU",a);
	else (void) printf("%g km",a*0.001*L_SCALE);
	(void) printf("\n");
	(void) printf("Eccentricity e = %g\n",e);
	(void) printf("Close-approach distance q = ");
	if (sim_units) (void) printf("%g AU",q);
	else (void) printf("%g km",q*0.001*L_SCALE);
	if (q <= sr) (void) printf(" (impact possible)");
	(void) printf("\n");
	(void) printf("Initial relative speed v = ");
	if (sim_units) (void) printf("%g x 30 km/s",v);
	else (void) printf("%g m/s",v*V_SCALE);
	(void) printf("\n");
	(void) printf("Relative speed at ");
	if (eb < 0) {
		vQ = sqrt(2*(eb + m/Q));
		(void) printf("apoapse vQ = ");
		}
	else {
		vQ = sqrt(2*eb);
		(void) printf("infinity v_inf = ");
		}
	if (sim_units) (void) printf("%g x 30 km/s",vQ);
	else (void) printf("%g m/s",vQ*V_SCALE);
	(void) printf("\n");
	(void) printf("Relative speed at ");
	if (q <= sr) {
		if (r > sr) q = sr;
		(void) printf("impact (approx)");
		}
	else (void) printf("periapse");
	(void) printf(" vq = ");
	if (q < sr) vq = v;
	else vq = sqrt(2*(eb + m/q));	
	if (sim_units) (void) printf("%g x 30 km/s",vq);
	else (void) printf("%g m/s",vq*V_SCALE);
	(void) printf("\n");
	(void) printf("Relative orb. ang. mom. per unit reduced mass h = "
				  "(%g,%g,%g) sim units\n",ang_mom[X],ang_mom[Y],ang_mom[Z]);
	}
Пример #9
0
int
main(int argc,char *argv[])
{
	FILE *fp;
	BOOLEAN sim_units;
	RUBBLE_PILE rp[MAX_NUM_FILES],*p;
	char infile[MAXPATHLEN],last_infile[MAXPATHLEN],outfile[MAXPATHLEN];
	double time = 0.0,old_time = 0.0;
	int n_files;

	setbuf(stdout,(char *)NULL);

	srand(getpid());

	if (argc > 1) {
		(void) fprintf(stderr,"%s takes no arguments\n",argv[0]);
		return 1;
		}

	fp = fopen(LOG_FILE,"r");
	if (fp) {
		(void) fclose(fp);
		if (!get_yn("Overwrite log file","y")) return 0;
		}

	fp = fopen(LOG_FILE,"w");
	if (!fp) {
		(void) fprintf(stderr,"Unable to open %s for writing\n",LOG_FILE);
		return 1;
		}

	sim_units = get_yn("Use simulation units (AU, M_sun, etc.)","n");

	n_files = 0;

	while (n_files < MAX_NUM_FILES) {
		infile[0] = '\0';
		(void) printf("File %i [or RETURN to quit]: ",n_files + 1);
		(void) fgets(infile,MAXPATHLEN,stdin);
		assert(strlen(infile));
		infile[strlen(infile) - 1] = '\0'; /* get rid of newline at end */
		if (!strlen(infile)) break;
		p = &rp[n_files];
		if (process(infile,p,sim_units,&time)) continue;
		if (n_files == 0)
			old_time = time;
		else if (time != old_time)
			time = 0.0; /* unless all times are the same, set to zero */
		(void) fprintf(fp,
					   "File number\t\t%i\n"
					   "Filename\t\t%s\n"
					   "Mass\t\t\t%e\n"
					   "Bulk radius\t\t%e\n"
					   "Bulk density\t\t%e\n"
					   "Position\t\t%+e\t%+e\t%+e\n"
					   "Velocity\t\t%+e\t%+e\t%+e\n"
					   "Spin\t\t\t%+e\t%+e\t%+e\n"
					   "Major axis\t\t%+f\t%+f\t%+f\n"
					   "Inter axis\t\t%+f\t%+f\t%+f\n"
					   "Minor axis\t\t%+f\t%+f\t%+f\n"
					   "Color\t\t\t%i\n"
					   "Aggregate ID\t\t%i\n\n",
					   n_files,infile,p->mass,p->radius,p->density,
					   p->pos[X],p->pos[Y],p->pos[Z],
					   p->vel[X],p->vel[Y],p->vel[Z],
					   p->spin[X],p->spin[Y],p->spin[Z],
					   p->axes[rp->axis_ord[X]][X],
					   p->axes[rp->axis_ord[X]][Y],
					   p->axes[rp->axis_ord[X]][Z],
					   p->axes[rp->axis_ord[Y]][X],
					   p->axes[rp->axis_ord[Y]][Y],
					   p->axes[rp->axis_ord[Y]][Z],
					   p->axes[rp->axis_ord[Z]][X],
					   p->axes[rp->axis_ord[Z]][Y],
					   p->axes[rp->axis_ord[Z]][Z],
					   p->color,p->agg_id);
		(void) strcpy(last_infile,infile);
		if (++n_files == MAX_NUM_FILES) (void) printf("File limit reached\n");
		}

	if (n_files == 0) {
		(void) fprintf(stderr,"No files specified!\n");
		return 1;
		}

	if (get_yn("Recenter barycentric position and velocity","y")) {
		VECTOR pos,vel,r,v;
		double total_mass;
		int i;

		total_mass = 0;
		ZERO_VEC(pos);
		ZERO_VEC(vel);
		for (i=0;i<n_files;i++) {
			COPY_VEC(rp[i].pos,r);
			SCALE_VEC(rp[i].pos,-1);
			rpuApplyPos(&rp[i]);
			SCALE_VEC(r,rp[i].mass);
			ADD_VEC(pos,r,pos);
			COPY_VEC(rp[i].vel,v);
			SCALE_VEC(rp[i].vel,-1);
			rpuApplyVel(&rp[i]);
			SCALE_VEC(v,rp[i].mass);
			ADD_VEC(vel,v,vel);
			total_mass += rp[i].mass;
			}
		NORM_VEC(pos,total_mass);
		NORM_VEC(vel,total_mass);
		for (i=0;i<n_files;i++) {
			SCALE_VEC(rp[i].pos,-1);
			SUB_VEC(rp[i].pos,pos,rp[i].pos);
			rpuApplyPos(&rp[i]);
			SCALE_VEC(rp[i].vel,-1);
			SUB_VEC(rp[i].vel,vel,rp[i].vel);
			rpuApplyVel(&rp[i]);
			}
		(void) fprintf(fp,"BARYCENTRIC CORRECTION APPLIED\n");
		}

	(void) fclose(fp);

	if (n_files == 2) show_encounter(rp,n_files,sim_units);

	do {
		(void) printf("Output file [default %s]: ",last_infile);
		(void) fgets(outfile,MAXPATHLEN,stdin);
		assert(strlen(outfile));
		outfile[strlen(outfile) - 1] = '\0';
		if (!strlen(outfile)) (void) strcpy(outfile,last_infile);
		outfile[MAXPATHLEN - 1] = '\0';
		if ((fp = fopen(outfile,"r"))) {
			(void) fclose(fp);
			if (!get_yn("Output file already exists...overwrite","n"))
				continue;
			}
		break;
		} while (/*CONSTCOND*/1);

	write_data(outfile,rp,n_files,time);

	for (--n_files;n_files>=0;n_files--)
		rpuFree(&rp[n_files]);

	(void) printf("Done!\n");

	return 0;
	}
Пример #10
0
static void
ss_analyze(SSDATA *data,int n_data,PROPERTIES *p)
{
	SSDATA *d;
	VECTOR r,v,l;
	int i,k,nc[NUM_COLORS],ncmax;

	assert(n_data > 0);

	p->total_mass = 0;
	ZERO_VEC(p->bnd_min);
	ZERO_VEC(p->bnd_max);
	ZERO_VEC(p->com_pos);
	ZERO_VEC(p->com_vel);
	ZERO_VEC(p->ang_mom);
	ZERO_VEC(p->vel_dsp);
	p->color = 0;

	for (i=0;i<NUM_COLORS;i++) nc[i] = 0;

	for (i=0;i<n_data;i++) {
		d = &data[i];
		p->total_mass += d->mass;
		COPY_VEC(d->pos,r);
		COPY_VEC(d->vel,v);
		if (i==0) {
			COPY_VEC(r,p->bnd_min);
			COPY_VEC(r,p->bnd_max);
			}
		else for (k=0;k<N_DIM;k++) {
			if (r[k] < p->bnd_min[k]) p->bnd_min[k] = r[k];
			if (r[k] > p->bnd_max[k]) p->bnd_max[k] = r[k];
			}
		SCALE_VEC(r,d->mass);
		ADD_VEC(p->com_pos,r,p->com_pos);
		SCALE_VEC(v,d->mass);
		ADD_VEC(p->com_vel,v,p->com_vel);
		CROSS(d->pos,d->vel,l);
		SCALE_VEC(l,d->mass);
		ADD_VEC(p->ang_mom,l,p->ang_mom);
		++nc[(int) d->color];
		}

	if (p->total_mass == 0) {
		(void) printf("WARNING: total mass = 0...will divide by N\n");
		p->total_mass = n_data;
		}

	NORM_VEC(p->com_pos,p->total_mass);
	NORM_VEC(p->com_vel,p->total_mass);
	NORM_VEC(p->ang_mom,p->total_mass);

	for (i=0;i<n_data;i++) {
		d = &data[i];
		SUB_VEC(d->vel,p->com_vel,v);
		for (k=0;k<N_DIM;k++)
			p->vel_dsp[k] += d->mass*SQ(v[k]);
		}

	for (k=0;k<N_DIM;k++)
		p->vel_dsp[k] = sqrt(p->vel_dsp[k]/p->total_mass);

	ncmax = 0;

	for (i=0;i<NUM_COLORS;i++)
		if (nc[i] > ncmax) {
			p->color = i;
			ncmax = nc[i];
			}

	calc_inertia(data,n_data,p->inertia);
	}