Integrate timelike geodesics and Fermi-Walker tetrads in ingoing Kerr-Schild coordinates, sampled at a configurable proper-time cadence. Add movie-track-samples to preserve CSV events as frames. Document usage and singularity guards, and cover analytic orbits, transport convergence, sampling, and CSV rendering.
72 lines
2.6 KiB
C
72 lines
2.6 KiB
C
#include "movie.h"
|
|
#include "observer_track.h"
|
|
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
|
|
static int nearly_equal(double a, double b) { return fabs(a - b) < 1e-12; }
|
|
|
|
int main(void) {
|
|
const char *path = "/tmp/gr_raytracing_observer_track.csv";
|
|
ObserverTrack generated = {0}, loaded = {0};
|
|
Movie movie = {0};
|
|
int result = 1;
|
|
if (observer_track_generate_minkowski_acceleration(&generated, 1.52, 2.0,
|
|
1.0 / 30.0) ||
|
|
generated.count != 61 ||
|
|
!nearly_equal(generated.samples[60].coordinate_time, 2.0) ||
|
|
!nearly_equal(generated.samples[60].tetrad[0][0],
|
|
sqrt(1.0 + 3.04 * 3.04)) ||
|
|
observer_track_write_csv(&generated, path) ||
|
|
observer_track_load_csv(&loaded, path) || loaded.count != generated.count ||
|
|
movie_init(&movie, &loaded, 0.0, 2.0, 30.0) || movie.frame_count != 61 ||
|
|
!nearly_equal(movie.frames[60].coordinate_time, 2.0) ||
|
|
!nearly_equal(movie.frames[60].observer.tetrad[0][3], -3.04))
|
|
goto done;
|
|
ObserverState interpolated;
|
|
double proper_time = 0.0;
|
|
if (observer_track_interpolate(&loaded, 1.0, &interpolated, &proper_time) ||
|
|
!nearly_equal(interpolated.coordinate_position[2],
|
|
-(sqrt(1.0 + 1.52 * 1.52) - 1.0) / 1.52) ||
|
|
!nearly_equal(proper_time, asinh(1.52) / 1.52))
|
|
goto done;
|
|
movie_destroy(&movie);
|
|
/* Nonuniform coordinate times must survive the row-per-frame path exactly. */
|
|
for (size_t i = 0; i < loaded.count; ++i)
|
|
loaded.samples[i].coordinate_time += 0.001 * i * i;
|
|
if (movie_init_track_samples(&movie, &loaded) ||
|
|
movie.frame_count != loaded.count)
|
|
goto done;
|
|
for (size_t i = 0; i < loaded.count; ++i) {
|
|
if (movie.frames[i].coordinate_time != loaded.samples[i].coordinate_time ||
|
|
movie.frames[i].observer.coordinate_time != loaded.samples[i].coordinate_time ||
|
|
movie.frames[i].proper_time != loaded.samples[i].proper_time)
|
|
goto done;
|
|
for (int a = 0; a < 4; ++a)
|
|
for (int mu = 0; mu < 4; ++mu)
|
|
if (movie.frames[i].observer.tetrad[a][mu] != loaded.samples[i].tetrad[a][mu])
|
|
goto done;
|
|
}
|
|
{
|
|
FILE *bad = fopen(path, "w");
|
|
ObserverTrack invalid = {0};
|
|
if (bad == NULL)
|
|
goto done;
|
|
if (fputs("0,0,0\n", bad) < 0 || fclose(bad) != 0)
|
|
goto done;
|
|
if (observer_track_load_csv(&invalid, path) == 0) {
|
|
observer_track_destroy(&invalid);
|
|
goto done;
|
|
}
|
|
}
|
|
result = 0;
|
|
done:
|
|
movie_destroy(&movie);
|
|
observer_track_destroy(&loaded);
|
|
observer_track_destroy(&generated);
|
|
remove(path);
|
|
if (result)
|
|
fputs("observer-track/movie regression failed\n", stderr);
|
|
return result;
|
|
}
|