Processed subhalo data and modified integrator to read and use new data structure
This commit is contained in:
parent
cb66caf6ba
commit
f8eae117dd
4 changed files with 281 additions and 62 deletions
|
|
@ -62,7 +62,7 @@ void Loadtxt::line_to_buf(std::vector<int> cols, std::string line, double *buffe
|
||||||
if (col++ == cols[idx]) buffer[idx++] = std::stod(num_as_string);
|
if (col++ == cols[idx]) buffer[idx++] = std::stod(num_as_string);
|
||||||
}
|
}
|
||||||
if (col++ == cols[idx]) buffer[idx++] = std::stod(line);
|
if (col++ == cols[idx]) buffer[idx++] = std::stod(line);
|
||||||
if (idx < n_cols) throw;
|
if (idx < n_cols) throw std::runtime_error("Read fewer columns than expected");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Below is a deomonstration. The file has multiple columns but we are only
|
// Below is a deomonstration. The file has multiple columns but we are only
|
||||||
|
|
|
||||||
103
main.cpp
103
main.cpp
|
|
@ -1,6 +1,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <boost/numeric/odeint.hpp>
|
#include <boost/numeric/odeint.hpp>
|
||||||
|
#include <Eigen/Geometry>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <gsl/gsl_spline.h>
|
#include <gsl/gsl_spline.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
@ -11,7 +12,7 @@
|
||||||
|
|
||||||
#include "loadtxt.h"
|
#include "loadtxt.h"
|
||||||
|
|
||||||
|
using double3 = Eigen::Vector3d;
|
||||||
|
|
||||||
// Our units are {kiloparsec, solar mass, gigayear}
|
// Our units are {kiloparsec, solar mass, gigayear}
|
||||||
constexpr double G = 4.498317481097514e-06;
|
constexpr double G = 4.498317481097514e-06;
|
||||||
|
|
@ -41,52 +42,78 @@ private:
|
||||||
gsl_spline *spline;
|
gsl_spline *spline;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Plummer {
|
void plummer(double M, double b, const double3& pos, double3& acc)
|
||||||
public:
|
{
|
||||||
Plummer(double M, double b)
|
double r2 = (pos[0]*pos[0] + pos[1]*pos[1] + pos[2]*pos[2] + b*b);
|
||||||
: M(M), b(b) {}
|
double r = sqrt(r2);
|
||||||
void calc_acceleration(const double *pos, double *acc)
|
double r3_inv = 1/(r*r2);
|
||||||
{
|
acc = -G*M*pos*r3_inv;
|
||||||
double r2 = (pos[0]*pos[0] + pos[1]*pos[1] + pos[2]*pos[2] + b*b);
|
}
|
||||||
double r = sqrt(r2);
|
|
||||||
double r3_inv = 1/(r*r2);
|
|
||||||
acc[0] = -G*M*pos[0]*r3_inv;
|
|
||||||
acc[1] = -G*M*pos[1]*r3_inv;
|
|
||||||
acc[2] = -G*M*pos[2]*r3_inv;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
void miyamoto_nagai(double M, double a, double b, double phi, double theta, const double3& pos, double3& acc)
|
||||||
double M, b;
|
{
|
||||||
};
|
// Construct new z-axis from the angles
|
||||||
|
double cos_theta = cos(theta);
|
||||||
|
double sin_theta = sqrt(1-cos_theta*cos_theta);
|
||||||
|
double cos_phi = cos(phi);
|
||||||
|
double sin_phi = sqrt(1-cos_phi*cos_phi);
|
||||||
|
Eigen::Vector3d old_z_axis = {cos_phi*sin_theta, sin_phi*sin_theta, cos_theta};
|
||||||
|
|
||||||
|
// Construct rotation
|
||||||
|
auto rot = Eigen::Quaternion<double>::FromTwoVectors(old_z_axis, Eigen::Vector3d::UnitZ());
|
||||||
|
|
||||||
|
// Rotate the position vector
|
||||||
|
auto new_pos = rot * pos;
|
||||||
|
|
||||||
|
// Calculate acceleration in new frame
|
||||||
|
Eigen::Vector3d acc_in_rotated_frame;
|
||||||
|
auto z_tmp = sqrt(new_pos[2]*new_pos[2] + b*b);
|
||||||
|
auto r2_tmp = new_pos[0]*new_pos[0] + new_pos[1]*new_pos[1] + (z_tmp + a)*(z_tmp + a);
|
||||||
|
auto r_tmp = sqrt(r2_tmp);
|
||||||
|
auto tmp = G*M / (r2_tmp*r_tmp);
|
||||||
|
acc_in_rotated_frame[0] = - tmp * new_pos[0];
|
||||||
|
acc_in_rotated_frame[1] = - tmp * new_pos[1];
|
||||||
|
acc_in_rotated_frame[2] = - tmp * new_pos[2] * (z_tmp + a)/z_tmp;
|
||||||
|
|
||||||
|
// Return to original frame
|
||||||
|
acc = rot.inverse() * acc_in_rotated_frame;
|
||||||
|
}
|
||||||
|
|
||||||
class Galaxy {
|
class Galaxy {
|
||||||
public:
|
public:
|
||||||
Galaxy(std::string file_name)
|
Galaxy(std::string file_name)
|
||||||
{
|
{
|
||||||
auto data = Loadtxt("file.dat", {1, 2, 3}).get_cols();
|
auto data = Loadtxt(file_name, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}).get_cols();
|
||||||
auto& t_data = data[0];
|
auto& t_data = data[0];
|
||||||
auto& halo_m_data = data[1];
|
|
||||||
auto& halo_b_data = data[2];
|
|
||||||
std::transform(begin(t_data), end(t_data), begin(t_data), [t0=t_data[0]](const double& x){ return x-t0; });
|
std::transform(begin(t_data), end(t_data), begin(t_data), [t0=t_data[0]](const double& x){ return x-t0; });
|
||||||
std::transform(halo_b_data.begin(), halo_b_data.end(), halo_b_data.begin(), [](const double& x){ return x*0.7664209365408798; });
|
for (int i=0; i<10; i++) interp[i] = Interp(t_data, data[i+1]);
|
||||||
interp_halo_m = Interp(t_data, halo_m_data);
|
|
||||||
interp_halo_b = Interp(t_data, halo_b_data);
|
|
||||||
}
|
}
|
||||||
void func(const std::array<double, 6> &y, std::array<double, 6> &f, const double t)
|
void func(const std::array<double, 6> &y, std::array<double, 6> &f, const double t)
|
||||||
{
|
{
|
||||||
double halo_m = interp_halo_m(t);
|
|
||||||
double halo_b = interp_halo_b(t);
|
|
||||||
Plummer plummer(halo_m, halo_b);
|
|
||||||
f[0] = y[3]; // vx -> x'
|
f[0] = y[3]; // vx -> x'
|
||||||
f[1] = y[4]; // vy -> y'
|
f[1] = y[4]; // vy -> y'
|
||||||
f[2] = y[5]; // vz -> z'
|
f[2] = y[5]; // vz -> z'
|
||||||
plummer.calc_acceleration(y.data(), f.data()+3); // a -> v'
|
double m_disk = interp[0](t);
|
||||||
|
double phi = interp[1](t);
|
||||||
|
double theta = interp[2](t);
|
||||||
|
double a_disk = interp[3](t);
|
||||||
|
double b_disk = interp[4](t);
|
||||||
|
double m_halo = interp[5](t);
|
||||||
|
double b_halo = interp[6](t);
|
||||||
|
double3 dalembert;
|
||||||
|
// for (int i=0; i<3; i++) dalembert[i] = interp[7+i](t);
|
||||||
|
dalembert = {0,0,0};
|
||||||
|
|
||||||
|
double3 acc_disk, acc_halo;
|
||||||
|
const double3 pos(y.data());
|
||||||
|
miyamoto_nagai(m_disk, a_disk, b_disk, phi, theta, pos, acc_disk);
|
||||||
|
plummer(m_halo, b_halo, pos, acc_halo);
|
||||||
|
for (int i=0; i<3; i++) f[3+i] = acc_disk[i] + acc_halo[i] + dalembert[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Interp interp_halo_m;
|
Interp interp[10];
|
||||||
Interp interp_halo_b;
|
} galaxy("subhalo_411321_parameters_processed.dat");
|
||||||
} galaxy("file.dat");
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
int integrate(const double y0[], const double t_max, const double stride_size, double y[])
|
int integrate(const double y0[], const double t_max, const double stride_size, double y[])
|
||||||
|
|
@ -113,14 +140,24 @@ int integrate(const double y0[], const double t_max, const double stride_size, d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
std::cout << "Hi" << std::endl;
|
std::cout << "Hi" << std::endl;
|
||||||
|
|
||||||
double y[12];
|
double y[12];
|
||||||
double y0[] = {80,0,0,0,80,0};
|
double y0[] = {80,0,0,0,80,0};
|
||||||
for (int i=0; i<8000; i++)
|
integrate(y0, 10, 10, y);
|
||||||
integrate(y0, 10, 10, y);
|
for (int i=0; i<12; i++) std::cout << y[i] << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// double y[12];
|
||||||
|
// double y0[] = {80,0,0,0,80,0};
|
||||||
|
// for (int i=0; i<8000; i++)
|
||||||
|
// integrate(y0, 10, 10, y);
|
||||||
|
|
||||||
/*double y0[] = {80,0,0,0,80,0};
|
/*double y0[] = {80,0,0,0,80,0};
|
||||||
double y[12];
|
double y[12];
|
||||||
|
|
|
||||||
51
plot.py
51
plot.py
|
|
@ -4,7 +4,7 @@
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import ctypes, subprocess
|
import ctypes, subprocess
|
||||||
|
|
||||||
recompile = True
|
recompile = False
|
||||||
|
|
||||||
if recompile:
|
if recompile:
|
||||||
p = subprocess.Popen('g++ -I/home/meiron/boost_1_72_0 -shared -o libmain.so -fPIC loadtxt.cpp main.cpp -lgsl'.split())
|
p = subprocess.Popen('g++ -I/home/meiron/boost_1_72_0 -shared -o libmain.so -fPIC loadtxt.cpp main.cpp -lgsl'.split())
|
||||||
|
|
@ -21,28 +21,43 @@ def integrate(y0, t_max, step_size=None):
|
||||||
y = np.array(y).reshape(size,6)
|
y = np.array(y).reshape(size,6)
|
||||||
return np.array(y), status
|
return np.array(y), status
|
||||||
|
|
||||||
def integrate_boost(y0, t_max, step_size=None):
|
|
||||||
y0 = (ctypes.c_double*6)(*y0)
|
|
||||||
if step_size is None: step_size = t_max
|
|
||||||
size = int(t_max // step_size) + 1
|
|
||||||
y = (ctypes.c_double*size*6)()
|
|
||||||
libmain.integrate_boost(y0, ctypes.c_double(t_max), ctypes.c_double(step_size), y)
|
|
||||||
y = np.array(y).reshape(size,6)
|
|
||||||
return np.array(y), 0
|
|
||||||
|
|
||||||
#gsl_success = libmain.gsl_success()
|
|
||||||
|
|
||||||
from pylab import *
|
from pylab import *
|
||||||
t_max = 10
|
t_max = 10
|
||||||
|
x_max = 85
|
||||||
ic = [80,0,0,0,80,0]
|
ic = [80,0,0,0,80,0]
|
||||||
res = integrate(ic, t_max, step_size=32/4096)
|
res = integrate(ic, t_max, step_size=32/4096)
|
||||||
x, y, z, vx, vy, vz = res[0].T
|
x, y, z, vx, vy, vz = res[0].T
|
||||||
zzz = x[-1]
|
|
||||||
plot(x,y)
|
|
||||||
|
|
||||||
res = integrate(ic, t_max)
|
|
||||||
x, y, z, vx, vy, vz = res[0].T
|
figure(figsize=(8,8))
|
||||||
plot(x,y,'o')
|
subplot(221)
|
||||||
print(zzz - x[-1])
|
plot(x, y)
|
||||||
|
plot(x[0], y[0], 'x')
|
||||||
gca().set_aspect('equal')
|
gca().set_aspect('equal')
|
||||||
|
xlabel('x')
|
||||||
|
ylabel('y')
|
||||||
|
xlim(-x_max,x_max)
|
||||||
|
ylim(-x_max,x_max)
|
||||||
|
|
||||||
|
subplot(223)
|
||||||
|
plot(x, z)
|
||||||
|
plot(x[0], z[0], 'x')
|
||||||
|
gca().set_aspect('equal')
|
||||||
|
xlabel('x')
|
||||||
|
ylabel('z')
|
||||||
|
xlim(-x_max,x_max)
|
||||||
|
ylim(-x_max,x_max)
|
||||||
|
|
||||||
|
subplot(224)
|
||||||
|
plot(y, z)
|
||||||
|
plot(y[0], z[0], 'x')
|
||||||
|
gca().set_aspect('equal')
|
||||||
|
xlabel('z')
|
||||||
|
ylabel('y')
|
||||||
|
xlim(-x_max,x_max)
|
||||||
|
ylim(-x_max,x_max)
|
||||||
|
|
||||||
|
subplots_adjust(wspace=0.25)
|
||||||
|
|
||||||
|
savefig('test_orbit.png')
|
||||||
show()
|
show()
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue