diff --git a/rebound/citations.py b/rebound/citations.py index eed025681..ce63ffdfb 100644 --- a/rebound/citations.py +++ b/rebound/citations.py @@ -164,7 +164,7 @@ def cite(sim): """ if sim.integrator == "trace": - txt += """The simulations were integrated using the hybrid time-reversible TRACE integrator \citep{reboundtrace}. """ + txt += """The simulations were integrated using the hybrid time-reversible TRACE integrator \\citep{reboundtrace}. """ bib += """@ARTICLE{reboundtrace, author = {{Lu}, Tiger and {Hernandez}, David M. and {Rein}, Hanno}, title = "{TRACE: a Time Reversible Algorithm for Close Encounters}", diff --git a/rebound/simulation.py b/rebound/simulation.py index 29634fb8f..9fc607933 100644 --- a/rebound/simulation.py +++ b/rebound/simulation.py @@ -26,7 +26,7 @@ (True, 16, "Error while reading binary file (file was closed).",), (True, 32, "Index out of range.",), (True, 64, "Error while trying to seek file.",), - (False, 128, "Encountered unkown field in file. File might have been saved with a different version of REBOUND."), + (False, 128, "Encountered unknown field in file. File might have been saved with a different version of REBOUND."), (True, 256, "Integrator type is not supported by this simulationarchive version."), (False, 512, "The binary file seems to be corrupted. An attempt has been made to read the uncorrupted parts of it."), (True, 1024, "Reading old Simulationarchives (version < 2) is no longer supported. If you need to read such an archive, use a REBOUND version <= 3.26.3"), diff --git a/rebound/tests/test_mercurius.py b/rebound/tests/test_mercurius.py index 54dd56bc5..286ce96b4 100644 --- a/rebound/tests/test_mercurius.py +++ b/rebound/tests/test_mercurius.py @@ -314,7 +314,7 @@ def get_sim(): # and are therefore machine dependent. self.assertLess(dE_mercurius,5e-6) # reasonable precision for mercurius self.assertLess(dE_mercurius/dE_whfast,1e-4) # at least 1e4 times better than whfast - self.assertLess(time_mercurius,time_ias15) # faster than ias15 + self.assertLess(time_mercurius,5.0*time_ias15) # not much slower than ias15 (often fails in unit tests) if sys.maxsize > 2**32: # 64 bit self.assertEqual(7060.644251181158, sim.particles[5].x) # Check if bitwise unchanged diff --git a/src/simulationarchive.c b/src/simulationarchive.c index c4f68d231..47e3a8b7d 100644 --- a/src/simulationarchive.c +++ b/src/simulationarchive.c @@ -75,12 +75,12 @@ void reb_simulation_create_from_simulationarchive_with_messages(struct reb_simul // Read SA snapshot if(fseek(inf, sa->offset[snapshot], SEEK_SET)){ *warnings |= REB_SIMULATION_BINARY_ERROR_SEEK; - reb_simulation_free(r); + //reb_simulation_free(r); return; } - if (r->simulationarchive_version<3){ + if (r->simulationarchive_version<2){ *warnings |= REB_SIMULATION_BINARY_ERROR_OLD; - reb_simulation_free(r); + //reb_simulation_free(r); return; }else{ // Version 2 or higher @@ -98,6 +98,13 @@ struct reb_simulation* reb_simulation_create_from_simulationarchive(struct reb_s return r; // might be null if error occured } +// Old 16 bit offsets. Used only to read old files. +struct reb_simulationarchive_blob16 { + int32_t index; + int16_t offset_prev; + int16_t offset_next; +}; + void reb_read_simulationarchive_from_stream_with_messages(struct reb_simulationarchive* sa, struct reb_simulationarchive* sa_index, enum reb_simulation_binary_error_codes* warnings){ // Assumes sa->inf is set to an open stream const int debug = 0; @@ -111,7 +118,9 @@ void reb_read_simulationarchive_from_stream_with_messages(struct reb_simulationa struct reb_binary_field field = {0}; sa->version = 0; double t0 = 0; - + int version_major = 0; // will be overwritten unless there is an error + int version_minor = 0; + int uses32bitoffsets = 1; // Cache descriptors struct reb_binary_field_descriptor fd_header = reb_binary_field_descriptor_for_name("header"); struct reb_binary_field_descriptor fd_t = reb_binary_field_descriptor_for_name("t"); @@ -137,6 +146,35 @@ void reb_read_simulationarchive_from_stream_with_messages(struct reb_simulationa sprintf(curvbuf,"%s%s",header+sizeof(struct reb_binary_field), reb_version_str); objects += fread(readbuf,sizeof(char),bufsize,sa->inf); + // Finding version_major/version_minor version + int c1=0, c2=0, c3=0; + for (int c=0; cinf); + size_t r3; + if (uses32bitoffsets){ + r3 = fread(&blob, sizeof(struct reb_simulationarchive_blob), 1, sa->inf); + }else{ + // Workaround for versions < 3.18 + struct reb_simulationarchive_blob16 blob16 = {0}; + r3 = fread(&blob16, sizeof(struct reb_simulationarchive_blob16), 1, sa->inf); + blob.index = blob16.index; + blob.offset_prev = blob16.offset_prev; + blob.offset_next = blob16.offset_next; + } int next_blob_is_corrupted = 0; if (r3!=1){ // Next snapshot is definitly corrupted. // Assume we have reached the end of the file. @@ -234,10 +282,16 @@ void reb_read_simulationarchive_from_stream_with_messages(struct reb_simulationa *warnings |= REB_SIMULATION_BINARY_WARNING_CORRUPTFILE; } if (i>0){ + size_t blobsize; + if (uses32bitoffsets){ + blobsize = sizeof(struct reb_simulationarchive_blob); + }else{ + blobsize = sizeof(struct reb_simulationarchive_blob16); + } // Checking the offsets. Acts like a checksum. - if (((int64_t)blob.offset_prev )+ ((int64_t)sizeof(struct reb_simulationarchive_blob)) != ftell(sa->inf) - ((int64_t)sa->offset[i]) ){ + if (((int64_t)blob.offset_prev )+ ((int64_t)blobsize) != ftell(sa->inf) - ((int64_t)sa->offset[i]) ){ // Offsets don't work. Next snapshot is definitly corrupted. Assume current one as well. - if (debug) printf("SA Error. Offset mismatch: %lu != %" PRIu64 ".\n",blob.offset_prev + sizeof(struct reb_simulationarchive_blob), (uint64_t)(ftell(sa->inf) - sa->offset[i]) ); + if (debug) printf("SA Error. Offset mismatch: %lu != %" PRIu64 ".\n",blob.offset_prev + blobsize, (uint64_t)(ftell(sa->inf) - sa->offset[i]) ); read_error = 1; break; }