double OblDeflectionTOA::toa_outgoing ( const double& b, const double& rspot, bool *prob ) { // costheta_check(cos_theta); //double dummy; // set globals OblDeflectionTOA_object = this; OblDeflectionTOA_b_value = b; // Note: Use an approximation to the integral near the surface // to avoid divergence problems, and then use the real // integral afterwards. See astro-ph/07030123 for the formula. // The idea is to compute the time for a ray emitted from the // surface, and subtract the time for a b=0 ray from r=rpole. // To avoid large numbers, part of the subtraction is accomplished in the integrand. // Note that for a b=0 ray, Delta T = int(1/(1-2*M/r), r), // which is r + 2 M ln (r - 2M) //double rsurf = modptr->R_at_costheta(cos_theta); double rsurf = rspot; double rpole = modptr->R_at_costheta(1.0); //std::cout << "toa_outgoing: rpole = " << rpole << std::endl; double toa = Integration( rsurf, get_rfinal(), OblDeflectionTOA_toa_integrand_minus_b0_wrapper ); double toa_b0_polesurf = (rsurf - rpole) + 2.0 * get_mass() * ( log( rsurf - 2.0 * get_mass() ) - log( rpole - 2.0 * get_mass() ) ); return double( toa - toa_b0_polesurf); }
double OblDeflectionTOA::toa_ingoing ( const double& b, const double& rspot, const double& cos_theta, bool *prob ) { //double dummy; //costheta_check(cos_theta); /* if ( b > bmax_outgoing(rspot) || b < bmin_ingoing(rspot, cos_theta) ) { std::cerr << "ERROR in OblDeflectionTOA::toa_ingoing(): b out-of-range." << std::endl; *prob = true; dummy = -7888.0; return dummy; } */ // std::cerr << "DEBUG: rcrit (km) = " << Units::nounits_to_cgs(this->rcrit(b,cos_theta), Units::LENGTH)/1.0e5 << std::endl; OblDeflectionTOA_object = this; OblDeflectionTOA_b_value = b; // See psi_ingoing. Use an approximate formula for the integral near rcrit, and the real formula elsewhere double rcrit = this->rcrit( b, cos_theta, &curve.problem ); double toa_in = rcrit / sqrt( 1 - 2.0 * get_mass() / rcrit ) * 2.0 * sqrt( 2.0 * (modptr->R_at_costheta(cos_theta) - rcrit) / (rcrit - 3.0 * get_mass()) ); // double rspot( modptr->R_at_costheta(cos_theta) ); return double( toa_in + this->toa_outgoing( b, rspot, &curve.problem ) ); }
double OblDeflectionTOA::toa_outgoing_u ( const double& b, const double& rspot, bool *prob ) { // costheta_check(cos_theta); //double dummy; // set globals double b_max=bmax_outgoing(rspot); OblDeflectionTOA_object = this; OblDeflectionTOA_b_over_r = b/rspot; // Note: Use an approximation to the integral near the surface // to avoid divergence problems, and then use the real // integral afterwards. See astro-ph/07030123 for the formula. // The idea is to compute the time for a ray emitted from the // surface, and subtract the time for a b=0 ray from r=rpole. // To avoid large numbers, part of the subtraction is accomplished in the integrand. // Note that for a b=0 ray, Delta T = int(1/(1-2*M/r), r), // which is r + 2 M ln (r - 2M) //double rsurf = modptr->R_at_costheta(cos_theta); double rsurf = rspot; double rpole = modptr->R_at_costheta(1.0); //std::cout << "toa_outgoing: rpole = " << rpole << std::endl; double toa(0.0); double split(0.99); if (b < 0.95*b_max) toa = Integration( 0.0, 1.0, OblDeflectionTOA_toa_integrand_minus_b0_wrapper_u,TRAPEZOIDAL_INTEGRAL_N/10 ); else if ( b < 0.9999999*b_max){ toa = Integration( 0.0, split, OblDeflectionTOA_toa_integrand_minus_b0_wrapper_u,TRAPEZOIDAL_INTEGRAL_N ); toa += Integration( split, 1.0, OblDeflectionTOA_toa_integrand_minus_b0_wrapper_u,TRAPEZOIDAL_INTEGRAL_N_1/10 ); //std::cout << "b/r = " << b/rspot << " b_max/r = " << b_max/rspot // << " b/b_max = " << b/b_max << " toa = " << toa << std::endl; } else{ toa = Integration( 0.0, split, OblDeflectionTOA_toa_integrand_minus_b0_wrapper_u,TRAPEZOIDAL_INTEGRAL_N ); toa += Integration( split, 1.0, OblDeflectionTOA_toa_integrand_minus_b0_wrapper_u,TRAPEZOIDAL_INTEGRAL_N_1*10 ); //std::cout << "*******b/r = " << b/rspot << " b_max/r = " << b_max/rspot // << " b/b_max = " << b/b_max << " toa = " << toa << std::endl; } //double toa = Integration( 0.0, 1.0, OblDeflectionTOA_toa_integrand_minus_b0_wrapper_u ); double toa_b0_polesurf = (rsurf - rpole) + 2.0 * get_mass() * ( log( rsurf - 2.0 * get_mass() ) - log( rpole - 2.0 * get_mass() ) ); return double( toa - toa_b0_polesurf); }
double OblDeflectionTOA::psi_ingoing ( const double& b, const double& cos_theta, bool *prob ) const { //costheta_check( cos_theta ); double rspot ( modptr->R_at_costheta( cos_theta ) ); //double dummy; // std::cout << "psi_ingoing: cos_theta = " << cos_theta << " b = " << b << " r = " << rspot << std::endl; /* if ( b > bmax_outgoing(rspot) || b < bmin_ingoing( rspot, cos_theta ) ) { std::cerr << "ERROR in OblDeflectionTOA::psi_ingoing(): b out-of-range." << std::endl; *prob = true; dummy = -7888.0; return dummy; } */ // set globals OblDeflectionTOA_object = this; OblDeflectionTOA_b_value = b; // See psi_outgoing. Use an approximate formula for the integral near rcrit, and the real formula elsewhere double rcrit = this->rcrit( b, cos_theta, &curve.problem ); double psi_in = 2.0 * sqrt( 2.0 * (rspot - rcrit) / (rcrit - 3.0 * get_mass()) ); return double( psi_in + this->psi_outgoing( b, rspot, 100.0, 100.0, &curve.problem ) ); }
void CODEGeom::get_mass(dMass& m,const Fvector& ref_point) { get_mass(m); Fvector l; l.sub(local_center(),ref_point); dMassTranslate(&m,l.x,l.y,l.z); }
void update_physics() { int bounce, mass; int length; length = get_reallength(); bounce = get_bounce(); mass = get_mass(); acc_old = acc; speed_old = speed; // update acceleration based on x axis acceleration sin_theta = -(float)1/17000; acc = sin_theta*7*MULT_FACTOR; // update speed. 1/UPDATE_RATE is time speed = speed + (acc)/(UPDATE_RATE); // update distance. 1/UPDATE_RATE is time distance = distance + (speed)/(UPDATE_RATE); if ( (distance > length || distance < 0) || ((distance == length || distance == 0) && end_reached == 0)) { // end reached // reset distance if (distance >= length) distance = length; if (distance <= 0) distance = 0; // send impact if (end_reached == 1) { // end already reached, impact already sent, so return DAC to zero normspeed = 0; } else { // first time end reached normspeed = ABS(speed)/80; /*DAC12_0DAT = mass*normspeed;*/ } speed = speed*bounce*(-0.1); end_reached = 1; } else if ( distance < length && distance > 0) { // rolling noise here end_reached = 0; normspeed = 0; /*DAC12_0DAT = get_rolling()*get_pot()*wavelet[wavelet_ind];*/ } else { /*DAC12_0DAT = 0; // prevent tick when starts to roll?*/ } wavelet_ind = (distance)%WAVELET_LEN; }
std::string spacecraft::human_readable() const { std::ostringstream s; s << "NEP spacecraft:" << std::endl << std::endl; s << "mass: " << get_mass() << std::endl; s << "thrust: " << get_thrust() << std::endl; s << "isp: " << get_isp() << std::endl; return s.str(); };
void CODEGeom::get_mass(dMass& m,const Fvector& ref_point, float density) { get_mass(m); dMassAdjust(&m,density*volume()); Fvector l; l.sub(local_center(),ref_point); dMassTranslate(&m,l.x,l.y,l.z); }
/* * void spawn_next_ball(); * * checks if the system has enough mass to spawn the new ball */ void spawn_next_ball() { //printf("%f/%f till next spawn\n", mass_of_system, next_ball_mass); if( mass_of_system >= next_ball_mass ) { all_spheres.resize(all_spheres.size()+1); all_spheres.push_back( generate_sphere(1) ); mass_of_system -= next_ball_mass; next_ball_radius = random_radius(); next_ball_mass = get_mass( next_ball_radius ); } }
/* * void gfxinit(); * * initializes the system prior to animating */ void gfxinit() { mass_of_system = 0.0; balls = NUMBER_OF_BALLS; all_spheres.resize(balls); current = 0.0; // LIGHTING GLfloat lightpos[4] = { 1.0, 0.0, 1.0, 1.0 }; // light position GLfloat lightamb[4] = { 0.0, 0.0, 0.0, 1.0 }; // ambient colour GLfloat lightdif[4] = { 1.0, 1.0, 1.0, 1.0 }; // diffuse colour GLfloat global_ambient[4] = {0.2, 0.2, 0.2, 1}; glLightfv(GL_LIGHT0, GL_POSITION, lightpos); // set the ambient light colour glLightfv(GL_LIGHT0, GL_AMBIENT, lightamb); // set the diffuse light colour glLightfv(GL_LIGHT0, GL_DIFFUSE, lightdif); // global ambient glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient); // turn on lighting glEnable(GL_LIGHTING); // enable light 0, all the other lights are off glEnable(GL_LIGHT0); // enable the depth buffer glEnable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); gluPerspective(60.0, 16/9., 0.1, 500.0); //glOrtho(-5.0,5.0,-5.0,5.0,1.0,20.0); glMatrixMode(GL_MODELVIEW); //gluLookAt(x, y, z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); //glRasterPos2i(10, 10); //glColor3f(1.0f, 1.0f, 1.0f); //glutBitmapString(GLUT_BITMAP_HELVETICA_18, (const unsigned char*)"dog"); glEnable ( GL_COLOR_MATERIAL ) ; glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ; glShadeModel(GL_SMOOTH); srand(time(NULL)); // seed for rand() calls // create all spheres for the initial system state int k; for( k = 0; k < all_spheres.size(); k++ ) { //setup all ball settings //printf("%d\n",k); all_spheres[k] = generate_sphere(0); } next_ball_radius = random_radius(); next_ball_mass = get_mass( next_ball_radius ); }
int kineticFeedback_mixt(struct RUNPARAMS *param, struct CELL *cell,struct PART *curp, REAL aexp, int level, REAL E, REAL dt){ // ----------------------------------------------------------// /// Inject an energy "E" in all cells of the oct contening /// the cell "cell" on kinetic form, radially to the center /// of the oct and uniformly in all cells // ----------------------------------------------------------// //REAL mtot_feedback = curp->mass* param->sn->ejecta_proportion; //printf("injecting_old m=%e, e=%e\t",curp->mass* param->sn->ejecta_proportion,E); REAL mtot_feedback = get_mass(param,curp,aexp,dt); if (mtot_feedback==0){ printf("WARNING null mass in kinetic feedback!\n"); return 1; } printf("injecting_new m=%e, e=%e\n",mtot_feedback ,E); int i; { //#define LOAD_FACTOR #ifdef LOAD_FACTOR REAL load_factor=10; REAL local_rho_min=FLT_MAX; for(i=0;i<8;i++){ struct OCT* oct = cell2oct(cell); struct CELL* curcell = &oct->cell[i]; local_rho_min = FMIN(curcell->field.d,local_rho_min); } REAL lf = FMIN(load_factor*curp->mass,local_rho_min); mtot_feedback += lf; for(i=0;i<8;i++){ struct OCT* oct = cell2oct(cell); struct CELL* curcell = &oct->cell[i]; curcell->field.d -= lf/8.; } #endif // LOAD_FACTOR } for(i=0;i<8;i++){ struct OCT* oct = cell2oct(cell); struct CELL* curcell = &oct->cell[i]; REAL dv = POW(0.5,3*level);// curent volume REAL dir_x[]={-1., 1.,-1., 1.,-1., 1.,-1., 1.};// diagonal projection REAL dir_y[]={-1.,-1., 1., 1.,-1.,-1., 1., 1.}; REAL dir_z[]={-1.,-1.,-1.,-1., 1., 1., 1., 1.}; REAL fact = 1.0; REAL m_e = mtot_feedback/8.; REAL d_e = m_e/dv; // ejecta density //--------------------------------------------------------------------------// // kinetic energy injection REAL E_e = E/8. *fact; REAL v_e = SQRT(2.*E_e/curcell->field.d); //printf("field.d=%e\n",curcell->field.d); REAL sqrt3 = SQRT(3.); curcell->field.u += v_e*dir_x[i]/sqrt3; curcell->field.v += v_e*dir_y[i]/sqrt3; curcell->field.w += v_e*dir_z[i]/sqrt3; //--------------------------------------------------------------------------// /* // momentum injection E_e = E/8. *(1.-fact) ; // uniform distribution v_e = SQRT(2.*E_e/d_e);// ejecta velocity / particle REAL vxe = curp->vx + v_e*dir_x[i]/sqrt3; // ejecta velocity /grid REAL vye = curp->vy + v_e*dir_y[i]/sqrt3; REAL vze = curp->vz + v_e*dir_z[i]/sqrt3; REAL d_i = curcell->field.d; // initial density REAL vxi = curcell->field.u; // initial velocity REAL vyi = curcell->field.v; REAL vzi = curcell->field.w; curcell->field.u = (vxi*d_i + vxe*d_e)/(d_i+d_e); //new velocity curcell->field.v = (vyi*d_i + vye*d_e)/(d_i+d_e); curcell->field.w = (vzi*d_i + vze*d_e)/(d_i+d_e); */ //--------------------------------------------------------------------------// // mass conservation curp->mass -= m_e; curcell->field.d += d_e; //new density //Energy conservation #ifdef DUAL_E struct Utype U; // conservative field structure W2U(&curcell->field, &U); // primitive to conservative U.eint*=1.+d_e/curcell->field.d; // compute new internal energy U2W(&U, &curcell->field); // back to primitive #else curcell->field.p*=1.+d_e/curcell->field.d; // compute new internal energy #endif getE(&curcell->field); //compute new total energy curcell->field.p=FMAX(curcell->field.p,PMIN); curcell->field.a=SQRT(GAMMA*curcell->field.p/curcell->field.d); // compute new sound speed } return 0; }
/* * void collision_response( struct sphere *b1, struct sphere *b2); * * performs collision response between two balls */ void collision_response(struct sphere *b1, struct sphere *b2) { b1->active = 1; b2->active = 1; double dx = b1->pos.x - b2->pos.x; double dy = b1->pos.y - b2->pos.y; double collision_angle = atan2(dy, dx); double b1_v, b2_v; b1_v = b1->velocity; b2_v = b2->velocity; double b1_vx, b1_vy, b2_vx, b2_vy; b1_vx = (b1->direction.x * b1_v); b1_vy = (b1->direction.y * b1_v); b2_vx = (b2->direction.x * b2_v); b2_vy = (b2->direction.y * b2_v); double mag1 = sqrt( b1_vx*b1_vx + b1_vy*b1_vy); double mag2 = sqrt( b2_vx*b2_vx + b2_vy*b2_vy); double dir1 = atan2(b1_vy, b1_vx); double dir2 = atan2(b2_vy, b2_vx); double b1_vx_new, b1_vy_new; double b2_vx_new, b2_vy_new; b1_vx_new = mag1 * cos(dir1-collision_angle); b1_vy_new = mag1 * sin(dir1-collision_angle); b2_vx_new = mag2 * cos(dir2-collision_angle); b2_vy_new = mag2 * sin(dir2-collision_angle); double b1_vx_final, b1_vy_final; double b2_vx_final, b2_vy_final; // get ball masses double m1 = get_mass(*b1), m2 = get_mass(*b2); b1_vx_final = (( m1 - m2)*b1_vx_new + (m2+m2)*b2_vx_new)/(m1+m2); b2_vx_final = (( m1 + m1)*b1_vx_new + (m2-m1)*b2_vx_new)/(m1+m2); b1_vy_final = b1_vy_new; b2_vy_final = b2_vy_new; b1_vx = cos(collision_angle)*b1_vx_final + cos(collision_angle+PI/2)*b1_vy_final; b1_vy = sin(collision_angle)*b1_vx_final + sin(collision_angle+PI/2)*b1_vy_final; b2_vx = cos(collision_angle)*b2_vx_final + cos(collision_angle+PI/2)*b2_vy_final; b2_vy = sin(collision_angle)*b2_vx_final + sin(collision_angle+PI/2)*b2_vy_final; b1->velocity = sqrt( pow(b1_vx,2) + pow(b1_vy,2)); b2->velocity = sqrt( pow(b2_vx,2) + pow(b2_vy,2)); b1->direction.x = b1_vx; b1->direction.y = b1_vy; normalize_dir(b1); b2->direction.x = b2_vx; b2->direction.y = b2_vy; normalize_dir(b2); b1->path = 0; b2->path = 0; b1->start_time = (double) clock(); b2->start_time = (double) clock(); //b1->active = 1; //b2->active = 1; // store before collision velocities //double b1_v, b2_v; //b1_v = b1->velocity; //b2_v = b2->velocity; //double b1_vx, b1_vy, b2_vx, b2_vy; //b1_vx = (b1->direction.x * b1_v); //b1_vy = (b1->direction.y * b1_v); //b2_vx = (b2->direction.x * b2_v); //b2_vy = (b2->direction.y * b2_v); // have x and y components of speed // get ball masses //double m1 = get_mass(*b1), m2 = get_mass(*b2); // need the new velocity components (after collision) //double b1_vx_new, b1_vy_new, b2_vx_new, b2_vy_new; // ball 1 new components //b1_vx_new = ((m1-m2) * b1_vx + (2*m2) * b2_vx)/(m1+m2); //b1_vy_new = ((m1-m2) * b1_vy + (2*m2) * b2_vy)/(m1+m2); // ball 2 new components //b2_vx_new = ((m2-m1) * b2_vx + (2*m1) * b1_vx)/(m1+m2); //b2_vy_new = ((m2-m1) * b2_vy + (2*m1) * b1_vy)/(m1+m2); // need to change direction to match new speeds //b1->direction.x = b1_vx_new; //b1->direction.y = b1_vy_new; //normalize_dir(b1); //b2->direction.x = b2_vx_new; //b2->direction.y = b2_vy_new; //normalize_dir(b2); //b1->velocity = // sqrt( pow(b1_vx_new,2) + pow(b1_vy_new,2)); //b2->velocity = // sqrt( pow(b2_vx_new,2) + pow(b2_vy_new,2)); // speeds updated //b1->path = 0; //b2->path = 0; //b1->start_time = (double) clock(); //b2->start_time = (double) clock(); }
int main(int argc, char *argv[]) { FILE **fp,*fp2; Input input; /* struct dirent **files; */ char **symbol,*tmp; int count,evnum,i,j,noweight=FALSE,stop=0,tech=ERD,tmpi,*Z,ZZ; int e,tof; /* int *step; */ double beamM,energy,*emax,*M,*M2,tmpd,***sto,***weight; gsto_table_t *table; if(argc == 1){ printf("Usage: tof_list [filename] [filename] ...\n"); exit(1); } fp = (FILE **) malloc(sizeof(FILE *)*(argc-1)); input.ecalib = (double *) malloc(sizeof(double)*(argc-1)); symbol = (char **) malloc(sizeof(char *)*(argc-1)); tmp = (char *) malloc(sizeof(char)*WORD_LENGTH); /* evnum = (int *) malloc(sizeof(int)*(argc-1)); */ /* step = (int *) malloc(sizeof(int)*(argc-1)); */ Z = (int *) malloc(sizeof(int)*(argc-1)); /* e = (double *) malloc(sizeof(double)*(argc-1)); */ emax = (double *) malloc(sizeof(double)*(argc-1)); M = (double *) malloc(sizeof(double)*(argc-1)); M2 = (double *) malloc(sizeof(double)*(argc-1)); /* tof = (double *) malloc(sizeof(double)*(argc-1)); */ sto = (double ***) malloc(sizeof(double **)*(argc-1)); weight = (double ***) malloc(sizeof(double **)*(argc-1)); read_input(&input); /* Useless filename.* feature for(i=0; (*tmp++ = *argv[1]++) != '.'; i++); for(j=i; j>0; j--,tmp--); if(*argv[1] == '*'){ argc = 1; for(j=scandir(".",&files,0,alphasort); j>0; j--) if(!strncmp(files[j]->d_name,tmp,i)) sscanf(files[j]->d_name,"%s",argv[argc++]); } else for(; i>-1; i--,argv[1]--); */ table=gsto_init(MAXELEMENTS, XSTR(STOPPING_DATA)); if(!table) { fprintf(stderr, "Could not init stopping table.\n"); return 0; } gsto_auto_assign_range(table, 1, MAXELEMENTS, 6, 6); /* TODO: only assign relevant stopping */ if(!gsto_load(table)) { fprintf(stderr, "Error in loading stopping.\n"); return 0; } for(i=0; i<argc-1; i++){ input.ecalib[i] = 0.0; symbol[i] = (char *) malloc(sizeof(char)*3); fp[i] = fopen(argv[i+1],"r"); if(fp[i] == NULL){ fprintf(stderr,"Could not open data file %s\n",argv[i+1]); exit(2); } while(*argv[i+1]++ != '.'); Z[i]=0; /* In Windows GCC, Z[i] is initialized with a large number as it's content, so this had to be done */ while(isdigit(*argv[i+1])) Z[i] = Z[i]*10 + *argv[i+1]++ - '0'; while(isalpha(*argv[i+1])) *symbol[i]++ = *argv[i+1]++; *symbol[i] = '\0'; while(!isupper(*--symbol[i])); ZZ = Z[i]; M[i] = get_mass(symbol[i],&ZZ); M2[i] = 0; tmpi = input.beamZ; beamM = get_mass(input.beam,&tmpi); emax[i] = input.beamE*4.0*ipow(cos(input.theta*C_DEG),2)*beamM*M[i]/ipow(beamM+M[i],2); sto[i] = set_sto(table, (Z[i])?Z[i]:ZZ,M[i],emax[i]*MAX_FACTOR); /* step[i] = get_step(emax[i]*MAX_FACTOR,sto[i]); */ weight[i] = set_weight(symbol[i],(Z[i])?Z[i]:ZZ,&input); Z[i] = ZZ; if(*argv[i+1] == '.'){ if(*++argv[i+1] == 'e'){ tmp = strcpy(tmp,symbol[i]); if((fp2 = fopen(strcat(tmp,".calib"),"r")) == NULL){ fprintf(stderr,"Could not locate calibration file %s\n",tmp); exit(3); } fscanf(fp2,"%lf",&input.ecalib[i]); fclose(fp2); } } } gsto_deallocate(table); /* Stopping data loaded in already, this is not used anymore */ for(i=0; i<argc-2; i++) for(j=i+1; j<argc-1; j++) if(!strcmp(symbol[i],symbol[j])) noweight = TRUE; char herp_c [100]; char *herp_d; int derp_n; char herpderp_1 [10]; char herpderp_2 [10]; float user_weight = 1.0; char herp_type [3]; char herp_scatter [6]; int herp_isotope=0; for(i=0;i<argc-1;i++){ tech = ERD; herp_d = (char *) malloc(sizeof(char)*WORD_LENGTH); /* Don't read the first ten lines, except the one line which contains the user-specified weight factor which is memorized. */ for(derp_n=0;derp_n<10;derp_n++){ fgets(herp_c, 100, fp[i]); if(derp_n == 1){ sscanf(herp_c, "%s %s", &herpderp_1, &herp_type); if (strcmp(herp_type, "RBS") == 0) tech = RBS; } if(derp_n == 2){ sscanf(herp_c, "%s %s %f", &herpderp_1, &herpderp_2, &user_weight); } if(derp_n == 5 && tech == 0){ sscanf(herp_c, "%s %s %s", &herpderp_1, &herpderp_2, herp_d); // Parse isotope from string while(isdigit(*herp_d)) herp_isotope = herp_isotope*10 + *herp_d++ - '0'; // Parse element sscanf(herp_d, "%s", herp_scatter); //printf("Scatter element: %s\n", herp_scatter); //printf("Scatter isotope: %i\n", herp_isotope); //printf("Scatter isotope mass: %8.4f\n", get_mass(herp_scatter, &herp_isotope)/C_U); // Get new mass and update values to scatter element. M2[i] = get_mass(herp_scatter, &herp_isotope); Z[i] = herp_isotope; /* emax[i] = input.beamE*4.0*ipow(cos(input.theta*C_DEG),2)*beamM*M[i]/ipow(beamM+M[i],2); #ifdef ZBL96 sto[i] = set_sto((Z[i])?Z[i]:ZZ,M[i],emax[i]*MAX_FACTOR); #else sto[i] = set_sto(stopping, (Z[i])?Z[i]:ZZ,M[i],emax[i]*MAX_FACTOR); #endif */ } } while(fscanf(fp[i], "%i %i %i", &tof, &e, &evnum) == 3){ if(e > 0){ if(tof == 0){ energy = e + ((double)(rand())/RAND_MAX) - 0.5; energy *= input.ecalib[i]; energy *= C_MEV; } else { energy = tof + ((double)(rand())/RAND_MAX) - 0.5; energy = get_energy(input.tof,energy*input.calib1 + input.calib2,M[i]); } tmpd = get_eloss(energy,sto[i]); energy = (tmpd > -0.1)?energy + tmpd*input.foil_thick:-1.0; if(energy > -0.1 && energy < emax[i]*MAX_FACTOR){ printf("%5.1f %5.1f ",ANGLE1,ANGLE2); //printf("%10.5lf %3d %8.4f ",energy/C_MEV,Z[i],M[i]/C_U); // Original printf("%10.5lf %3d %8.4f ",energy/C_MEV, Z[i], (tech == 0)?M2[i]/C_U:M[i]/C_U); printf("%s %6.3f %5d\n",(tech)?"ERD":"RBS",(noweight)?1.0:get_weight(weight[i],energy)*user_weight,evnum); } } } fclose(fp[i]); } #if 0 for(i=0; i<argc-1; i++) fscanf(fp[i],"%lf %lf %d",&tof[i],&e[i],&evnum[i]); for(count=0; stop<argc-1; count++){ stop = 0; for(i=0; i<argc-1; i++){ if(!evnum[i]) stop++; else if(count == evnum[i]){ if((int)(e[i])){ if(!(int)(tof[i])) tof[i] = e[i]; /* Randomize input channel */ tof[i] += -0.5 + ((double)(rand())/RAND_MAX); /* Calculate energy from channel */ tof[i] = (input.ecalib[i]>0.00001)?tof[i]*input.ecalib[i]:get_energy(input.tof,tof[i]*input.calib1 + input.calib2,M[i]); /* Calculate and add energy loss in carbon foil */ tmpd = get_eloss(tof[i],sto[i]); tof[i] = (tmpd>-0.1)?tof[i]+tmpd*input.foil_thick:-1.0; /* for(j=0; j<step[i]; j++) tof[i] += get_eloss(tof[i],sto[i])*input.foil_thick/step[i]; */ if(tof[i]>-0.1 && tof[i]<emax[i]*MAX_FACTOR){ printf("%5.1f %5.1f ",ANGLE1,ANGLE2); printf("%10.5lf %3d %8.4f ",tof[i]/C_MEV,Z[i],M[i]/C_U); printf("%s %6.3f %5d\n",(tech)?"ERD":"RBS",(noweight)?1.0:get_weight(weight[i],tof[i]),evnum[i]); } } if(fscanf(fp[i],"%lf %lf %d",&tof[i],&e[i],&evnum[i]) != 3) evnum[i] = 0; } } } #endif for(i=0; i<argc-1; i++) fclose(fp[i]); exit(0); }
double OblDeflectionTOA::rcrit_zero_func ( const double& rc, const double& b ) const { return double( rc - b * sqrt( 1.0 - 2.0 * get_mass() / rc ) ); }
/* * void animate(); * * This acts as the idle function, whenever the system is idle, animte() is * called. The end of animate() forces display() to refresh */ void animate() { int j; double mass_before; while((double) clock() == current){} // waits for next time step current = (double) clock(); // remove tails int k; for( k = 0; k < tails.size(); k++) { tails[k].life--; if(tails[k].life <= 0) { tails.erase(tails.begin()+k); } } for(j = 0; j < all_spheres.size(); j++) { // DECAY double decay = ((double) rand() / RAND_MAX); if( all_spheres[j].radius>0.0) { if( decay <= DECAY_PROB && all_spheres[j].active) { mass_before = get_mass(all_spheres[j].radius); all_spheres[j].radius -= 0.00045; mass_of_system += ( mass_before - get_mass(all_spheres[j].radius)); if(dust_shown) { struct dust tail; double rad = all_spheres[j].radius; tail.pos.x = all_spheres[j].pos.x + (((double) rand() / RAND_MAX) * (2*rad) - rad); tail.pos.y = all_spheres[j].pos.y + (((double) rand() / RAND_MAX) * (2*rad) - rad); tail.pos.z = all_spheres[j].pos.z + (((double) rand() / RAND_MAX) * (2*rad) - rad); tail.color = all_spheres[j].color; tail.life = 75; tails.resize(tails.size()+1); tails.push_back(tail); } } }else{ all_spheres.erase(all_spheres.begin()+j); balls--; break; } // END DECAY if(all_spheres[j].path == 0) { //linear paths // advance position on vector all_spheres[j] = move_on_vector(all_spheres[j]); }else if(all_spheres[j].path == 1) { // bezier curves for path if( all_spheres[j].interval < 1.0) { // advance position on curve move_on_curve(&all_spheres[j]); } else { // generate a new curve generate_curve(&all_spheres[j]); } } } // set window and call display to refresh screen glutSetWindow(window); glutPostRedisplay(); }
/* * void collision_response( struct sphere *b1, struct sphere *b2); * * performs collision response between two balls */ void collision_response(struct sphere *b1, struct sphere *b2) { b1->active = 1; b2->active = 1; if(response == 1) { // proper 3D collisions using equation provided on // http://www.plasmaphysics.org.uk/programs/coll3d_cpp.htm double R = 1.0; double m1 = get_mass(b1->radius); double m2 = get_mass(b2->radius); double r1 = b1->radius; double r2 = b2->radius; double x1 = b1->pos.x; double y1 = b1->pos.y; double z1 = b1->pos.z; double x2 = b2->pos.x; double y2 = b2->pos.y; double z2 = b2->pos.z; double vx1 = (b1->direction.x * b1->velocity); double vy1 = (b1->direction.y * b1->velocity); double vz1 = (b1->direction.z * b1->velocity); double vx2 = (b2->direction.x * b2->velocity); double vy2 = (b2->direction.y * b2->velocity); double vz2 = (b2->direction.z * b2->velocity); double pi,r12,m21,d,v,theta2,phi2,st,ct,sp,cp,vx1r,vy1r,vz1r,fvz1r, thetav,phiv,dr,alpha,beta,sbeta,cbeta,dc,sqs,t,a,dvz2, vx2r,vy2r,vz2r,x21,y21,z21,vx21,vy21,vz21,vx_cm,vy_cm,vz_cm; // **** initialize some variables **** pi=acos(-1.0E0); //error=0; r12=r1+r2; m21=m2/m1; x21=x2-x1; y21=y2-y1; z21=z2-z1; vx21=vx2-vx1; vy21=vy2-vy1; vz21=vz2-vz1; vx_cm = (m1*vx1+m2*vx2)/(m1+m2) ; vy_cm = (m1*vy1+m2*vy2)/(m1+m2) ; vz_cm = (m1*vz1+m2*vz2)/(m1+m2) ; // **** calculate relative distance and relative speed *** d=sqrt(x21*x21 +y21*y21 +z21*z21); v=sqrt(vx21*vx21 +vy21*vy21 +vz21*vz21); // **** shift coordinate system so that ball 1 is at the origin *** x2=x21; y2=y21; z2=z21; // **** boost coordinate system so that ball 2 is resting *** vx1=-vx21; vy1=-vy21; vz1=-vz21; // **** find the polar coordinates of the location of ball 2 *** theta2=acos(z2/d); if (x2==0 && y2==0) {phi2=0;} else {phi2=atan2(y2,x2);} st=sin(theta2); ct=cos(theta2); sp=sin(phi2); cp=cos(phi2); // **** express the velocity vector of ball 1 in a rotated coordinate // system where ball 2 lies on the z-axis ****** vx1r=ct*cp*vx1+ct*sp*vy1-st*vz1; vy1r=cp*vy1-sp*vx1; vz1r=st*cp*vx1+st*sp*vy1+ct*vz1; fvz1r = vz1r/v ; if (fvz1r>1) {fvz1r=1;} // fix for possible rounding errors else if (fvz1r<-1) {fvz1r=-1;} thetav=acos(fvz1r); if (vx1r==0 && vy1r==0) {phiv=0;} else {phiv=atan2(vy1r,vx1r);} // **** calculate the normalized impact parameter *** dr=d*sin(thetav)/r12; // **** calculate impact angles if balls do collide *** alpha=asin(-dr); beta=phiv; sbeta=sin(beta); cbeta=cos(beta); // **** calculate time to collision *** t=(d*cos(thetav) -r12*sqrt(1-dr*dr))/v; // **** update positions and reverse the coordinate shift *** x2=x2+vx2*t +x1; y2=y2+vy2*t +y1; z2=z2+vz2*t +z1; x1=(vx1+vx2)*t +x1; y1=(vy1+vy2)*t +y1; z1=(vz1+vz2)*t +z1; // *** update velocities *** a=tan(thetav+alpha); dvz2=2*(vz1r+a*(cbeta*vx1r+sbeta*vy1r))/((1+a*a)*(1+m21)); vz2r=dvz2; vx2r=a*cbeta*dvz2; vy2r=a*sbeta*dvz2; vz1r=vz1r-m21*vz2r; vx1r=vx1r-m21*vx2r; vy1r=vy1r-m21*vy2r; // **** rotate the velocity vectors back and add the initial velocity // vector of ball 2 to retrieve the original coordinate system **** vx1=ct*cp*vx1r-sp*vy1r+st*cp*vz1r +vx2; vy1=ct*sp*vx1r+cp*vy1r+st*sp*vz1r +vy2; vz1=ct*vz1r-st*vx1r +vz2; vx2=ct*cp*vx2r-sp*vy2r+st*cp*vz2r +vx2; vy2=ct*sp*vx2r+cp*vy2r+st*sp*vz2r +vy2; vz2=ct*vz2r-st*vx2r +vz2; b1->direction.x = vx1; b1->direction.y = vy1; // 3D b1->direction.z = vz1; normalize_dir(b1); b2->direction.x = vx2; b2->direction.y = vy2; b2->direction.z = vz2; normalize_dir(b2); b1->velocity = sqrt( pow(vx1,2) + pow(vy1,2) + pow(vz1,2)); b2->velocity = sqrt( pow(vx2,2) + pow(vy2,2) + pow(vz2,2)); }else{ // store before collision velocities double b1_v, b2_v; b1_v = b1->velocity; b2_v = b2->velocity; double b1_vx, b1_vy, b2_vx, b2_vy; // 3D double b1_vz, b2_vz; b1_vx = (b1->direction.x * b1_v); b1_vy = (b1->direction.y * b1_v); // 3D b1_vz = (b1->direction.z * b1_v); b2_vx = (b2->direction.x * b2_v); b2_vy = (b2->direction.y * b2_v); // 3D b2_vz = (b2->direction.z * b2_v); // have x and y components of speed // get ball masses double m1 = get_mass(b1->radius), m2 = get_mass(b2->radius); // need the new velocity components (after collision) double b1_vx_new, b1_vy_new, b2_vx_new, b2_vy_new; // 3D double b1_vz_new, b2_vz_new; // ball 1 new components b1_vx_new = ((m1-m2) * b1_vx + (2*m2) * b2_vx)/(m1+m2); b1_vy_new = ((m1-m2) * b1_vy + (2*m2) * b2_vy)/(m1+m2); // 3D b1_vz_new = ((m1-m2) * b1_vz + (2*m2) * b2_vz)/(m1+m2); // ball 2 new components b2_vx_new = ((m2-m1) * b2_vx + (2*m1) * b1_vx)/(m1+m2); b2_vy_new = ((m2-m1) * b2_vy + (2*m1) * b1_vy)/(m1+m2); // 3D b2_vz_new = ((m2-m1) * b2_vz + (2*m1) * b1_vz)/(m1+m2); // need to change direction to match new speeds b1->direction.x = b1_vx_new; b1->direction.y = b1_vy_new; // 3D b1->direction.z = b1_vz_new; normalize_dir(b1); b2->direction.x = b2_vx_new; b2->direction.y = b2_vy_new; b2->direction.z = b2_vz_new; normalize_dir(b2); b1->velocity = sqrt( pow(b1_vx_new,2) + pow(b1_vy_new,2) + pow(b1_vz_new,2)); b2->velocity = sqrt( pow(b2_vx_new,2) + pow(b2_vy_new,2) + pow(b2_vz_new,2)); // speeds updated } b1->path = 0; b2->path = 0; b1->start_time = (double) clock(); b2->start_time = (double) clock(); }
void KJoint::print_joint_for_debug() const { //std::cout<<"Transform"<<std::endl<<m_transform<<std::endl<<"Mass Offset"<<std::endl<<m_mass_offset<<std::endl //<<"Angles"<<std::endl<<m_angle<<" "<<m_min_angle<<" "<<m_max_angle<<std::endl<<"MotorId: "<<m_motor_id<<std::endl; std::cout<<"Mass: "<<get_mass()<<std::endl<<"Endpoint, Offset, Endpoint:"<<std::endl<<(Eigen::Matrix<double,4 ,3>()<<m_mass_endpoint, m_mass_offset, get_endpoint()).finished()<<std::endl; }
void CODEGeom::add_self_mass(dMass& m,const Fvector& ref_point) { dMass self_mass; get_mass(self_mass,ref_point); dMassAdd(&m,&self_mass); }