void reb_output_binary(struct reb_simulation* r, char* filename){ #ifdef MPI char filename_mpi[1024]; sprintf(filename_mpi,"%s_%d",filename,r->mpi_id); FILE* of = fopen(filename_mpi,"wb"); #else // MPI FILE* of = fopen(filename,"wb"); #endif // MPI if (of==NULL){ reb_exit("Can not open file."); } // Output header. const char str[] = "REBOUND Binary File. Version: "; size_t lenheader = strlen(str)+strlen(reb_version_str); fwrite(str,sizeof(char),strlen(str),of); fwrite(reb_version_str,sizeof(char), strlen(reb_version_str),of); while (lenheader<64){ //padding char space = ' '; if (lenheader==63) space = '\0'; fwrite(&space,sizeof(char),1,of); lenheader += 1; } // Output main simulation structure fwrite(r,sizeof(struct reb_simulation),1,of); // Output particles fwrite(r->particles,sizeof(struct reb_particle),r->N,of); // Output variational configuration structures if (r->var_config_N){ fwrite(r->var_config,sizeof(struct reb_variational_configuration),r->var_config_N,of); } // Output IAS15 temporary arrays (needed for bit-by-bit reproducability) if (r->ri_ias15.allocatedN){ int N3 = r->ri_ias15.allocatedN; fwrite(r->ri_ias15.at,sizeof(double),N3,of); fwrite(r->ri_ias15.x0,sizeof(double),N3,of); fwrite(r->ri_ias15.v0,sizeof(double),N3,of); fwrite(r->ri_ias15.a0,sizeof(double),N3,of); fwrite(r->ri_ias15.csx,sizeof(double),N3,of); fwrite(r->ri_ias15.csv,sizeof(double),N3,of); fwrite(r->ri_ias15.csa0,sizeof(double),N3,of); reb_save_dp7(&(r->ri_ias15.g) ,N3,of); reb_save_dp7(&(r->ri_ias15.b) ,N3,of); reb_save_dp7(&(r->ri_ias15.csb),N3,of); reb_save_dp7(&(r->ri_ias15.e) ,N3,of); reb_save_dp7(&(r->ri_ias15.br) ,N3,of); reb_save_dp7(&(r->ri_ias15.er) ,N3,of); } fclose(of); }
void reb_output_binary(struct reb_simulation* r, char* filename){ #ifdef MPI char filename_mpi[1024]; sprintf(filename_mpi,"%s_%d",filename,r->mpi_id); FILE* of = fopen(filename_mpi,"wb"); #else // MPI FILE* of = fopen(filename,"wb"); #endif // MPI if (of==NULL){ reb_exit("Can not open file."); } fwrite(r,sizeof(struct reb_simulation),1,of); fwrite(r->particles,sizeof(struct reb_particle),r->N,of); fclose(of); }
void reb_output_velocity_dispersion(struct reb_simulation* r, char* filename){ const int N = r->N; // Algorithm with reduced roundoff errors (see wikipedia) struct reb_vec3d A = {.x=0, .y=0, .z=0}; struct reb_vec3d Q = {.x=0, .y=0, .z=0}; for (int i=0;i<N;i++){ struct reb_vec3d Aim1 = A; struct reb_particle p = r->particles[i]; A.x = A.x + (p.vx-A.x)/(double)(i+1); if (r->integrator==REB_INTEGRATOR_SEI){ A.y = A.y + (p.vy+1.5*r->ri_sei.OMEGA*p.x-A.y)/(double)(i+1); }else{ A.y = A.y + (p.vy-A.y)/(double)(i+1); } A.z = A.z + (p.vz-A.z)/(double)(i+1); Q.x = Q.x + (p.vx-Aim1.x)*(p.vx-A.x); if (r->integrator==REB_INTEGRATOR_SEI){ Q.y = Q.y + (p.vy+1.5*r->ri_sei.OMEGA*p.x-Aim1.y)*(p.vy+1.5*r->ri_sei.OMEGA*p.x-A.y); }else{ Q.y = Q.y + (p.vy-Aim1.y)*(p.vy-A.y); } Q.z = Q.z + (p.vz-Aim1.z)*(p.vz-A.z); } #ifdef MPI int N_tot = 0; struct reb_vec3d A_tot = {.x=0, .y=0, .z=0}; struct reb_vec3d Q_tot = {.x=0, .y=0, .z=0}; MPI_Reduce(&N, &N_tot, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); MPI_Reduce(&A, &A_tot, 3, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); MPI_Reduce(&Q, &Q_tot, 3, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD); if (r->mpi_id!=0) return; #else int N_tot = N; struct reb_vec3d A_tot = A; struct reb_vec3d Q_tot = Q; #endif Q_tot.x = sqrt(Q_tot.x/(double)N_tot); Q_tot.y = sqrt(Q_tot.y/(double)N_tot); Q_tot.z = sqrt(Q_tot.z/(double)N_tot); FILE* of = fopen(filename,"a"); if (of==NULL){ reb_exit("Can not open file."); } fprintf(of,"%e\t%e\t%e\t%e\t%e\t%e\t%e\n",r->t,A_tot.x,A_tot.y,A_tot.z,Q_tot.x,Q_tot.y,Q_tot.z); fclose(of); }
void reb_output_ascii(struct reb_simulation* r, char* filename){ const int N = r->N; #ifdef MPI char filename_mpi[1024]; sprintf(filename_mpi,"%s_%d",filename,r->mpi_id); FILE* of = fopen(filename_mpi,"a"); #else // MPI FILE* of = fopen(filename,"a"); #endif // MPI if (of==NULL){ reb_exit("Can not open file."); } for (int i=0;i<N;i++){ struct reb_particle p = r->particles[i]; fprintf(of,"%e\t%e\t%e\t%e\t%e\t%e\n",p.x,p.y,p.z,p.vx,p.vy,p.vz); } fclose(of); }
void reb_output_orbits(struct reb_simulation* r, char* filename){ const int N = r->N; #ifdef MPI char filename_mpi[1024]; sprintf(filename_mpi,"%s_%d",filename,r->mpi_id); FILE* of = fopen(filename_mpi,"a"); #else // MPI FILE* of = fopen(filename,"a"); #endif // MPI if (of==NULL){ reb_exit("Can not open file."); } struct reb_particle com = r->particles[0]; for (int i=1;i<N;i++){ struct reb_orbit o = reb_tools_particle_to_orbit(r->G, r->particles[i],com); fprintf(of,"%e\t%e\t%e\t%e\t%e\t%e\t%e\t%e\t%e\n",r->t,o.a,o.e,o.inc,o.Omega,o.omega,o.l,o.P,o.f); com = reb_get_com_of_pair(com,r->particles[i]); } fclose(of); }
void reb_output_binary_positions(struct reb_simulation* r, char* filename){ const int N = r->N; #ifdef MPI char filename_mpi[1024]; sprintf(filename_mpi,"%s_%d",filename,r->mpi_id); FILE* of = fopen(filename_mpi,"wb"); #else // MPI FILE* of = fopen(filename,"wb"); #endif // MPI if (of==NULL){ reb_exit("Can not open file."); } for (int i=0;i<N;i++){ struct reb_vec3d v; v.x = r->particles[i].x; v.y = r->particles[i].y; v.z = r->particles[i].z; fwrite(&(v),sizeof(struct reb_vec3d),1,of); } fclose(of); }