External potential (EXTPOT_GAL) cleaned up

This commit is contained in:
Yohai Meiron 2020-03-24 20:37:23 -04:00
parent d7332be188
commit 562ea9618a
4 changed files with 230 additions and 487 deletions

View file

@ -110,6 +110,8 @@ void Config::error_checking()
throw std::runtime_error("The number of live black holes (live_smbh_count) can be 0, 1, or 2");
if (binary_smbh_pn && (live_smbh_count!=2))
throw std::runtime_error("Post-Newtonian gravity (binary_smbh_pn=true) requires live_smbh_count=2");
if (binary_smbh_pn && (pn_c <= 0))
throw std::runtime_error("Post-Newtonian gravity (binary_smbh_pn=true) requires pn_c > 0");
if (live_smbh_custom_eps == eps) live_smbh_custom_eps = -1;
if (live_smbh_output && (live_smbh_count == 0))
throw std::runtime_error("Black hole output (live_smbh_output=true) requires at least one live black hole (live_smbh_count)");
@ -122,6 +124,14 @@ void Config::error_checking()
for (int i; i<7; i++)
if (!((pn_usage[i] == 0) || (pn_usage[i] == 1)))
throw std::runtime_error("PN usage array (pn_usage) must have ones and zeros only");
if (ext_units_physical && ((norm_mass == 0) || (norm_length == 0)))
throw std::runtime_error("Physical units for external gravity (ext_units_physical) requires ext_norm_mass and ext_norm_length to be positive numbers");
if ((ext_m_bulge > 0) && (ext_b_bulge < 0))
throw std::runtime_error("To use external bulge gravity, please specify positive ext_m_bulge and ext_b_bulge");
if ((ext_m_halo_plummer > 0) && (ext_b_halo_plummer < 0))
throw std::runtime_error("To use external Plummer halo gravity, please specify positive ext_m_halo_plummer and ext_b_halo_plummer");
if ((ext_m_disk > 0) && ((ext_a_disk < 0) || (ext_b_disk < 0)))
throw std::runtime_error("To use external disk gravity, please specify positive ext_m_disk, ext_a_disk and ext_b_disk");
}
Config::Config(std::string file_name)
@ -137,16 +147,30 @@ Config::Config(std::string file_name)
eta = get_parameter<double>(dictionary, "eta");
input_file_name = get_parameter<std::string>(dictionary, "input_file_name", "data.con");
dt_min_warning = get_parameter<bool>(dictionary, "dt_min_warning", false);
live_smbh_count = get_parameter<int>(dictionary, "live_smbh_count", 0);
live_smbh_custom_eps = get_parameter<double>(dictionary, "live_smbh_custom_eps", -1);
live_smbh_output = get_parameter<bool>(dictionary, "live_smbh_output", false);
live_smbh_neighbor_output = get_parameter<bool>(dictionary, "live_smbh_neighbor_output", false);
live_smbh_neighbor_number = get_parameter<int>(dictionary, "live_smbh_neighbor_number", 10);
binary_smbh_pn = get_parameter<bool>(dictionary, "binary_smbh_pn", false);
binary_smbh_influence_sphere_output = get_parameter<bool>(dictionary, "binary_smbh_influence_sphere_output", false);
binary_smbh_influence_radius_factor = get_parameter<double>(dictionary, "binary_smbh_influence_radius_factor", 10.);
binary_smbh_pn = get_parameter<bool>(dictionary, "binary_smbh_pn", false);
pn_usage = get_parameter<std::vector<int>>(dictionary, "pn_usage", std::vector<int>({1,1,1,1,1,1,1}));
pn_c = get_parameter<double>(dictionary, "pn_c", 500);
pn_c = get_parameter<double>(dictionary, "pn_c", 0);
ext_units_physical = get_parameter<bool>(dictionary, "ext_units_physical", false);
norm_mass = get_parameter<double>(dictionary, "norm_mass", !ext_units_physical);
norm_length = get_parameter<double>(dictionary, "norm_length", !ext_units_physical);
ext_m_bulge = get_parameter<double>(dictionary, "ext_m_bulge", 0);
ext_b_bulge = get_parameter<double>(dictionary, "ext_b_bulge", -1);
ext_m_disk = get_parameter<double>(dictionary, "ext_m_disk", 0);
ext_a_disk = get_parameter<double>(dictionary, "ext_a_disk", -1);
ext_b_disk = get_parameter<double>(dictionary, "ext_b_disk", -1);
ext_m_halo_plummer = get_parameter<double>(dictionary, "ext_m_halo_plummer", 0);
ext_b_halo_plummer = get_parameter<double>(dictionary, "ext_b_halo_plummer", -1);
error_checking();
}

View file

@ -25,6 +25,17 @@ public:
double binary_smbh_influence_radius_factor;
std::vector<int> pn_usage;
double pn_c;
bool ext_units_physical;
double norm_mass;
double norm_length;
double ext_m_bulge;
double ext_b_bulge;
double ext_m_disk;
double ext_a_disk;
double ext_b_disk;
double ext_m_halo_plummer;
double ext_b_halo_plummer;
private:
using Dictionary = std::unordered_map<std::string,std::string>;
Dictionary read_config_file(const std::string file_name);

View file

@ -29,67 +29,87 @@ output_format = HDF5
dt_min_warning = false
#############################################
####################
# EXTERNAL GRAVITY #
####################
ext_units_physical = true
norm_mass = 1e5
norm_length = 10
# TODO add the option to normalize using other units
# Notice that if physical units are used, the "a" and "b" parameters are in kiloparsec, not parsec!
ext_m_bulge = 1e5
ext_b_bulge = 20
ext_m_disk = 1e6
ext_a_disk = 80
ext_b_disk = 70
ext_m_halo_plummer = 1e6
ext_b_halo_plummer = 200.
####################################
## LIVE SUPERMASSIVE BLACK HOLE(S) #
####################################
#
## There is special treatment for particles representing supermassive black holes (SMBHs): they are integrated at every time step, they can have custom softening in SMBH-SMBH interactions, and post Newtonian terms can be added to the gravity.
#
## The number of SMBH particles. Can be 0 (no SMBH), 1, or 2. [default: 0]
#live_smbh_count = 0
#
## Custom softening length for SMBH-SMBH interactions (can also be zero). If non-negative, the custom softening is applied. [default: -1]
#live_smbh_custom_eps = 0
#
## Output additional diagnostics about live SMBHs. [default: false]
##TODO# dt_bh
#live_smbh_output = true
#
## Output additional diagnostics about the SMBH's (or SMBHs') nearest neighbours (number could be set as shown below). [default: false]
#live_smbh_neighbor_output = true
#
## Number of nearest neighbours to the SMBH (or SMBHs) to include in output. [default: 10]
#live_smbh_neighbor_number = 10
#
###################################
# LIVE SUPERMASSIVE BLACK HOLE(S) #
## BINARY SUPERMASSIVE BLACK HOLE #
###################################
# There is special treatment for particles representing supermassive black holes (SMBHs): they are integrated at every time step, they can have custom softening in SMBH-SMBH interactions, and post Newtonian terms can be added to the gravity.
# The number of SMBH particles. Can be 0 (no SMBH), 1, or 2. [default: 0]
live_smbh_count = 2
# Custom softening length for SMBH-SMBH interactions (can also be zero). If non-negative, the custom softening is applied. [default: -1]
live_smbh_custom_eps = 0
# Output additional diagnostics about live SMBHs. [default: false]
#TODO# dt_bh
live_smbh_output = true
# Output additional diagnostics about the SMBH's (or SMBHs') nearest neighbours (number could be set as shown below). [default: false]
live_smbh_neighbor_output = true
# Number of nearest neighbours to the SMBH (or SMBHs) to include in output. [default: 10]
live_smbh_neighbor_number = 10
##################################
# BINARY SUPERMASSIVE BLACK HOLE #
##################################
# The following parameters can be set when `live_smbh_count` is 2.
# Output additional diagnostics about the SMBH's sphere of influence (size could be set as shown below). [default: false]
binary_smbh_influence_sphere_output = true
# The influence sphere is centred at the binary SMBH's centre of mass, and its radius is the semi-major axis of the binary times the factor below. [default: 10.0]
binary_smbh_influence_radius_factor = 3.162277660168379497918067e+03
# Add post Newtonian terms to SMBH-SMBH gravity. [default: false]
binary_smbh_pn = true
# A mask array (zeros and ones) determining whether or not to use specific post-Newtonian terms.
# The elements represent {0, 1, 2, 2.5, 3, 3.5, spin}
pn_usage = {1, 1, 1, 1, 0, 0, 0}
# The speed of light in N-body units [default: 500]
pn_c = 477.12
####################################
# Negative powers of two #
####################################
# -1 1/2 0.5 #
# -2 1/4 0.25 #
# -3 1/8 0.125 #
# -4 1/16 0.0625 #
# -5 1/32 0.03125 #
# -6 1/64 0.015625 #
# -7 1/128 0.0078125 #
# -8 1/256 0.00390625 #
# -9 1/512 0.001953125 #
# -10 1/1024 0.0009765625 #
# -11 1/2048 0.00048828125 #
# -12 1/4096 0.000244140625 #
# -13 1/8192 0.0001220703125 #
# -14 1/16384 0.00006103515625 #
# -15 1/32768 0.000030517578125 #
# -16 1/65536 0.0000152587890625 #
####################################
#
## The following parameters can be set when `live_smbh_count` is 2.
#
## Output additional diagnostics about the SMBH's sphere of influence (size could be set as shown below). [default: false]
#binary_smbh_influence_sphere_output = true
#
## The influence sphere is centred at the binary SMBH's centre of mass, and its radius is the semi-major axis of the binary times the factor below. [default: 10.0]
#binary_smbh_influence_radius_factor = 3.162277660168379497918067e+03
#
## Add post Newtonian terms to SMBH-SMBH gravity. [default: false]
#binary_smbh_pn = true
#
## A mask array (zeros and ones) determining whether or not to use specific post-Newtonian terms.
## The elements represent {0, 1, 2, 2.5, 3, 3.5, spin}
#pn_usage = {1, 1, 1, 1, 0, 0, 0}
#
## The speed of light in N-body units [default: 500]
#pn_c = 477.12
#
#####################################
## Negative powers of two #
#####################################
## -1 1/2 0.5 #
## -2 1/4 0.25 #
## -3 1/8 0.125 #
## -4 1/16 0.0625 #
## -5 1/32 0.03125 #
## -6 1/64 0.015625 #
## -7 1/128 0.0078125 #
## -8 1/256 0.00390625 #
## -9 1/512 0.001953125 #
## -10 1/1024 0.0009765625 #
## -11 1/2048 0.00048828125 #
## -12 1/4096 0.000244140625 #
## -13 1/8192 0.0001220703125 #
## -14 1/16384 0.00006103515625 #
## -15 1/32768 0.000030517578125 #
## -16 1/65536 0.0000152587890625 #
#####################################

View file

@ -56,12 +56,11 @@ Last redaction : 2019.04.16 12:55
#include "config.h"
Config *config;
//#define NORM // Physical normalization
#define NORM // Physical normalization
//#define EXTPOT // external potential (BH? or galactic?)
#define EXTPOT // external potential (BH? or galactic?)
//#define EXTPOT_BH // BH - usually NB units
//#define EXTPOT_GAL // Galactic B+D+H PK - usually physical units
//#define EXTPOT_GAL_DEH // Dehnen Galactic - usually physical units
//#define EXTPOT_GAL_LOG // Log Galactic - usually physical units
@ -112,6 +111,7 @@ Config *config;
#include <algorithm>
#include <numeric>
#include <stdexcept>
#define G6_NPIPE 2048
#include "grape6.h"
@ -217,7 +217,11 @@ struct double3 {
data[2] /= c;
return *this;
}
double norm()
double norm2() const
{
return data[0]*data[0]+data[1]*data[1]+data[2]*data[2];
}
double norm() const
{
return sqrt(data[0]*data[0]+data[1]*data[1]+data[2]*data[2]);
}
@ -234,6 +238,11 @@ double3 operator*(const double3& a, const double& c)
return double3(a.data[0]*c, a.data[1]*c, a.data[2]*c);
}
double operator*(const double3& a, const double3& b)
{
return a.data[0]*b.data[0]+a.data[1]*b.data[1]+a.data[2]*b.data[2];
}
double3 operator/(const double3& a, const double& c)
{
return double3(a.data[0]/c, a.data[1]/c, a.data[2]/c);
@ -292,9 +301,7 @@ double3 a2by18, a1by6, aby2;
/* normalization... */
#ifdef NORM
double m_norm, r_norm, v_norm, t_norm;
#endif
double eps_BH=0.0;
@ -302,14 +309,6 @@ double eps_BH=0.0;
#ifdef EXTPOT
#ifdef EXTPOT_GAL
double m_bulge, a_bulge, b_bulge,
m_disk, a_disk, b_disk,
m_halo, a_halo, b_halo, // NOTE there are other "halo" variables in EXTPOT_GAL_LOG
x2_ij, y2_ij, z2_ij, // NOTE this variable exist also in EXTPOT_GAL_LOG
r_tmp, r2_tmp, z_tmp, z2_tmp;
#endif
#ifdef EXTPOT_GAL_DEH
double m_ext, r_ext, g_ext,
tmp_r2, tmp_r3, dum, dum2, dum3, dum_g, tmp_g;
@ -624,254 +623,72 @@ void write_bh_nb_data(double time_cur, int N, double m[], double3 x[], double3 v
fclose(out);
}
void calc_ext_grav_zero()
{
#ifdef EXTPOT
/* Define the external potential for all particles on all nodes */
ni = n_act;
for (i=0; i<ni; i++)
class External_gravity {
public:
External_gravity() {}
void calc_plummer(const int n_act, const double3 x[], const double3 v[], double pot[], double3 a[], double3 adot[], int mode)
{
pot_ext[i] = 0.0;
/* This funcion calculates gravity due to a smeared point source using Plummer softening. The `mode` parameter determines whether we use the BH, bulge, or halo. */ // TODO change mode to class enum?
double m, b;
switch (mode) {
case 0: m=m_bh; b=b_bh; break;
case 1: m=m_bulge; b=b_bulge; break;
case 2: m=m_halo; b=b_halo; break;
default:
throw std::runtime_error("Unknown mode in external_gravity.calc_plummer");
}
for (int i=0; i<n_act; i++) {
double r2 = SQR(b);
r2 += x[i].norm2();
double r = sqrt(r2);
double rv_ij = v[i]*x[i];
double tmp = m / r;
pot[i] -= tmp;
tmp /= r2;
a[i] -= tmp * x[i];
adot[i] -= tmp * (v[i] - 3*rv_ij * x[i]/r2);
}
}
#ifdef EXTPOT_GAL
for (i=0; i<ni; i++)
void calc_disk(const int n_act, double3 x[], double3 v[], double pot[], double3 a[], double3 adot[]) //TODO change x and v to const
{
/*
x_ij = x_act[i][0]-x_ext;
y_ij = x_act[i][1]-y_ext;
z_ij = x_act[i][2]-z_ext;
vx_ij = v_act[i][0]-vx_ext;
vy_ij = v_act[i][1]-vy_ext;
vz_ij = v_act[i][2]-vz_ext;
*/
x_ij = x_act[i][0];
y_ij = x_act[i][1];
z_ij = x_act[i][2];
vx_ij = v_act[i][0];
vy_ij = v_act[i][1];
vz_ij = v_act[i][2];
x2_ij = SQR(x_ij);
y2_ij = SQR(y_ij);
z2_ij = SQR(z_ij);
/* for BULGE */
r2 = SQR(b_bulge);
r2 += x_ij*x_ij + y_ij*y_ij + z_ij*z_ij; r = sqrt(r2);
rv_ij = vx_ij*x_ij + vy_ij*y_ij + vz_ij*z_ij;
tmp = m_bulge / r;
pot_ext[i] -= tmp;
tmp /= r2;
a[i][0] -= tmp * x_ij;
a[i][1] -= tmp * y_ij;
a[i][2] -= tmp * z_ij;
adot[i][0] -= tmp * (vx_ij - 3.0*rv_ij * x_ij/r2);
adot[i][1] -= tmp * (vy_ij - 3.0*rv_ij * y_ij/r2);
adot[i][2] -= tmp * (vz_ij - 3.0*rv_ij * z_ij/r2);
/* for DISK */
z2_tmp = z2_ij + SQR(b_disk);
z_tmp = sqrt(z2_tmp);
r2_tmp = x2_ij + y2_ij + SQR(z_tmp + a_disk);
r_tmp = sqrt(r2_tmp);
pot_ext[i] -= m_disk / r_tmp;
tmp = m_disk / (r2_tmp*r_tmp);
a[i][0] -= tmp * x_ij;
a[i][1] -= tmp * y_ij;
a[i][2] -= tmp * z_ij * (z_tmp + a_disk)/z_tmp;
tmp = m_disk / (z_tmp*r2_tmp*r2_tmp*r_tmp);
adot[i][0] += tmp * (- vx_ij*z_tmp*r2_tmp
+ 3.0*x_ij*vx_ij*x_ij*z_tmp
+ 3.0*x_ij*vy_ij*y_ij*z_tmp
+ 3.0*x_ij*vz_ij*z_ij*SQR(z_tmp + a_disk) );
adot[i][1] += tmp * (- vy_ij*z_tmp*r2_tmp
+ 3.0*y_ij*vx_ij*x_ij*z_tmp
+ 3.0*y_ij*vy_ij*y_ij*z_tmp
+ 3.0*y_ij*vz_ij*z_ij*SQR(z_tmp + a_disk) );
adot[i][2] += tmp * (- vz_ij*(z_tmp + a_disk)*( x2_ij*( z2_tmp*z_tmp + a_disk*SQR(b_disk) ) +
y2_ij*( z2_tmp*z_tmp + a_disk*SQR(b_disk) ) -
( 2.0*a_disk*(SQR(z_ij) - SQR(b_disk))*z_tmp +
2.0*SQR(z_ij*z_ij) +
SQR(b_disk)*SQR(z_ij) -
SQR(b_disk)*( SQR(a_disk) + SQR(b_disk) ) ) )
+ 3.0*vx_ij*x_ij*z_ij*z2_tmp*(z_tmp + a_disk)
+ 3.0*vy_ij*y_ij*z_ij*z2_tmp*(z_tmp + a_disk) ) / z2_tmp ;
/* for HALO */
r2 = SQR(b_halo);
r2 += x_ij*x_ij + y_ij*y_ij + z_ij*z_ij; r = sqrt(r2);
rv_ij = vx_ij*x_ij + vy_ij*y_ij + vz_ij*z_ij;
tmp = m_halo / r;
pot_ext[i] -= tmp;
tmp /= r2;
a[i][0] -= tmp * x_ij;
a[i][1] -= tmp * y_ij;
a[i][2] -= tmp * z_ij;
adot[i][0] -= tmp * (vx_ij - 3.0*rv_ij * x_ij/r2);
adot[i][1] -= tmp * (vy_ij - 3.0*rv_ij * y_ij/r2);
adot[i][2] -= tmp * (vz_ij - 3.0*rv_ij * z_ij/r2);
} /* i */
#endif
#ifdef EXTPOT_GAL_DEH
for (i=0; i<ni; i++)
{
x_ij = x_act[i][0];
y_ij = x_act[i][1];
z_ij = x_act[i][2];
vx_ij = v_act[i][0];
vy_ij = v_act[i][1];
vz_ij = v_act[i][2];
tmp_r = sqrt( SQR(x_ij) + SQR(y_ij) + SQR(z_ij) );
tmp_r2 = SQR(tmp_r);
tmp_r3 = POW3(tmp_r);
dum = tmp_r/(tmp_r + r_ext);
dum2 = SQR(dum);
dum3 = POW3(dum);
dum_g = pow( dum , -g_ext );
pot_ext[i] -= ((m_ext/r_ext) / (2.0-g_ext) ) * ( 1.0 - dum2 * dum_g );
tmp = (m_ext/tmp_r3) * dum3 * dum_g;
a[i][0] -= tmp * x_ij;
a[i][1] -= tmp * y_ij;
a[i][2] -= tmp * z_ij;
rv_ij = ( vx_ij*x_ij + vy_ij*y_ij + vz_ij*z_ij );
tmp = ( m_ext/POW3(tmp_r+r_ext) ) * dum_g;
tmp_g = ((r_ext*g_ext + 3.0*tmp_r)/(tmp_r2*(tmp_r+r_ext)) ) * rv_ij;
adot[i][0] += tmp * ( tmp_g * x_ij - vx_ij );
adot[i][1] += tmp * ( tmp_g * y_ij - vy_ij );
adot[i][2] += tmp * ( tmp_g * z_ij - vz_ij );
} /* i */
#endif
/* For simple Log potential... */
#ifdef EXTPOT_GAL_LOG
for (i=0; i<ni; i++)
{
x_ij = x_act[i][0];
y_ij = x_act[i][1];
z_ij = x_act[i][2];
vx_ij = v_act[i][0];
vy_ij = v_act[i][1];
vz_ij = v_act[i][2];
r2 = SQR(x_ij) + SQR(y_ij) + SQR(z_ij);
rv_ij = 2.0 * ( vx_ij*x_ij + vy_ij*y_ij + vz_ij*z_ij );
r2_r2_halo = (r2 + r2_halo);
pot_ext[i] -= 0.5*v2_halo * log(1.0 + r2/r2_halo);
tmp = v2_halo/r2_r2_halo;
a[i][0] -= tmp * x_ij;
a[i][1] -= tmp * y_ij;
a[i][2] -= tmp * z_ij;
tmp /= (r2 + r2_halo);
adot[i][0] += tmp * (rv_ij * x_ij - r2_r2_halo * vx_ij);
adot[i][1] += tmp * (rv_ij * y_ij - r2_r2_halo * vy_ij);
adot[i][2] += tmp * (rv_ij * z_ij - r2_r2_halo * vz_ij);
} /* i */
#endif
/* For simple Plummer potential... */
#ifdef EXTPOT_BH
for (i=0; i<ni; i++)
{
x_ij = x_act[i][0];
y_ij = x_act[i][1];
z_ij = x_act[i][2];
vx_ij = v_act[i][0];
vy_ij = v_act[i][1];
vz_ij = v_act[i][2];
r2 = SQR(b_bh);
r2 += x_ij*x_ij + y_ij*y_ij + z_ij*z_ij; r = sqrt(r2);
rv_ij = vx_ij*x_ij + vy_ij*y_ij + vz_ij*z_ij;
tmp = m_bh / r;
pot_ext[i] -= tmp;
tmp /= r2;
a[i][0] -= tmp * x_ij;
a[i][1] -= tmp * y_ij;
a[i][2] -= tmp * z_ij;
adot[i][0] -= tmp * (vx_ij - 3.0*rv_ij * x_ij/r2);
adot[i][1] -= tmp * (vy_ij - 3.0*rv_ij * y_ij/r2);
adot[i][2] -= tmp * (vz_ij - 3.0*rv_ij * z_ij/r2);
} /* i */
#endif
#endif // EXTPOT
}
int i = 0;
double z2_tmp = x[i][2]*x[i][2] + b_disk*b_disk;
double z_tmp = sqrt(z2_tmp);
double r2_tmp = x[i][0]*x[i][0] + x[i][1]*x[i][1] + SQR(z_tmp + a_disk);
double r_tmp = sqrt(r2_tmp);
pot[i] -= m_disk / r_tmp;
double tmp = m_disk / (r2_tmp*r_tmp);
a[i][0] -= tmp * x_ij;
a[i][1] -= tmp * y_ij;
a[i][2] -= tmp * z_ij * (z_tmp + a_disk)/z_tmp;
tmp = m_disk / (z_tmp*r2_tmp*r2_tmp*r_tmp);
adot[i][0] += tmp * (- v[i][0]*z_tmp*r2_tmp
+ 3*x[i][0]*v[i][0]*x[i][0]*z_tmp
+ 3*x[i][0]*v[i][1]*x[i][1]*z_tmp
+ 3*x[i][0]*v[i][2]*x[i][2]*SQR(z_tmp + a_disk));
adot[i][1] += tmp * (- v[i][1]*z_tmp*r2_tmp
+ 3*x[i][1]*v[i][0]*x[i][0]*z_tmp
+ 3*x[i][1]*v[i][1]*x[i][1]*z_tmp
+ 3*x[i][1]*v[i][2]*x[i][2]*SQR(z_tmp + a_disk));
adot[i][2] += tmp * (- v[i][2]*(z_tmp + a_disk)*(x[i][0]*(z2_tmp*z_tmp + a_disk*SQR(b_disk)) +
x[i][1]*(z2_tmp*z_tmp + a_disk*SQR(b_disk)) -
(2*a_disk*(SQR(x[i][2]) - SQR(b_disk))*z_tmp +
2*SQR(x[i][2]*x[i][2]) +
SQR(b_disk)*SQR(x[i][2]) -
SQR(b_disk)*( SQR(a_disk) + SQR(b_disk))))
+ 3*v[i][0]*x[i][0]*x[i][2]*z2_tmp*(z_tmp + a_disk)
+ 3*v[i][1]*x[i][1]*x[i][2]*z2_tmp*(z_tmp + a_disk)) / z2_tmp;
}
//private: //TODO make private
double m_bh, b_bh,
m_bulge, b_bulge,
m_disk, a_disk, b_disk,
m_halo, b_halo;
};
External_gravity external_gravity;
void calc_self_grav(double t, double eps2, double &g6_calls, int n_loc,
int n_act, int ind_act[],
@ -911,16 +728,25 @@ void calc_self_grav(double t, double eps2, double &g6_calls, int n_loc,
#endif
}
void calc_ext_grav()
void calc_ext_grav(int n_act, double3 *x_act_new, double3 *v_act_new, double3 *a_act_new, double3* adot_act_new)
{
#ifdef EXTPOT
/* Define the external potential for all active particles on all nodes */
ni = n_act;
int ni = n_act;
for (i=0; i<ni; i++)
if (external_gravity.m_bulge > 0)
external_gravity.calc_plummer(ni, x_act_new,v_act_new, pot_act_ext, a_act_new, adot_act_new, 1); // Bulge
if (external_gravity.m_disk > 0)
external_gravity.calc_disk(ni, x_act_new,v_act_new, pot_act_ext, a_act_new, adot_act_new); // Disk
if (external_gravity.m_halo > 0)
external_gravity.calc_plummer(ni, x_act_new,v_act_new, pot_act_ext, a_act_new, adot_act_new, 2); // Halo
for (int i=0; i<ni; i++)
{
pot_act_ext[i] = 0.0;
}
@ -929,117 +755,6 @@ for (i=0; i<ni; i++)
get_CPU_time(&CPU_tmp_real0, &CPU_tmp_user0, &CPU_tmp_syst0);
#endif
#ifdef EXTPOT_GAL
for (i=0; i<ni; i++)
{
/*
x_ij = x_act_new[i][0]-x_ext;
y_ij = x_act_new[i][1]-y_ext;
z_ij = x_act_new[i][2]-z_ext;
vx_ij = v_act_new[i][0]-vx_ext;
vy_ij = v_act_new[i][1]-vy_ext;
vz_ij = v_act_new[i][2]-vz_ext;
*/
x_ij = x_act_new[i][0];
y_ij = x_act_new[i][1];
z_ij = x_act_new[i][2];
vx_ij = v_act_new[i][0];
vy_ij = v_act_new[i][1];
vz_ij = v_act_new[i][2];
x2_ij = SQR(x_ij);
y2_ij = SQR(y_ij);
z2_ij = SQR(z_ij);
/* for BULGE */
r2 = SQR(b_bulge);
r2 += x_ij*x_ij + y_ij*y_ij + z_ij*z_ij; r = sqrt(r2);
rv_ij = vx_ij*x_ij + vy_ij*y_ij + vz_ij*z_ij;
tmp = m_bulge / r;
pot_act_ext[i] -= tmp;
tmp /= r2;
a_act_new[i][0] -= tmp * x_ij;
a_act_new[i][1] -= tmp * y_ij;
a_act_new[i][2] -= tmp * z_ij;
adot_act_new[i][0] -= tmp * (vx_ij - 3.0*rv_ij * x_ij/r2);
adot_act_new[i][1] -= tmp * (vy_ij - 3.0*rv_ij * y_ij/r2);
adot_act_new[i][2] -= tmp * (vz_ij - 3.0*rv_ij * z_ij/r2);
/* for DISK */
z2_tmp = z2_ij + SQR(b_disk);
z_tmp = sqrt(z2_tmp);
r2_tmp = x2_ij + y2_ij + SQR(z_tmp + a_disk);
r_tmp = sqrt(r2_tmp);
pot_act_ext[i] -= m_disk / r_tmp;
tmp = m_disk / (r2_tmp*r_tmp);
a_act_new[i][0] -= tmp * x_ij;
a_act_new[i][1] -= tmp * y_ij;
a_act_new[i][2] -= tmp * z_ij * (z_tmp + a_disk)/z_tmp;
tmp = m_disk / (z_tmp*r2_tmp*r2_tmp*r_tmp);
adot_act_new[i][0] += tmp * (- vx_ij*z_tmp*r2_tmp
+ 3.0*x_ij*vx_ij*x_ij*z_tmp
+ 3.0*x_ij*vy_ij*y_ij*z_tmp
+ 3.0*x_ij*vz_ij*z_ij*SQR(z_tmp + a_disk) );
adot_act_new[i][1] += tmp * (- vy_ij*z_tmp*r2_tmp
+ 3.0*y_ij*vx_ij*x_ij*z_tmp
+ 3.0*y_ij*vy_ij*y_ij*z_tmp
+ 3.0*y_ij*vz_ij*z_ij*SQR(z_tmp + a_disk) );
adot_act_new[i][2] += tmp * (- vz_ij*(z_tmp + a_disk)*( x2_ij*( z2_tmp*z_tmp + a_disk*SQR(b_disk) ) +
y2_ij*( z2_tmp*z_tmp + a_disk*SQR(b_disk) ) -
( 2.0*a_disk*(SQR(z_ij) - SQR(b_disk))*z_tmp +
2.0*SQR(z_ij*z_ij) +
SQR(b_disk)*SQR(z_ij) -
SQR(b_disk)*( SQR(a_disk) + SQR(b_disk) ) ) )
+ 3.0*vx_ij*x_ij*z_ij*z2_tmp*(z_tmp + a_disk)
+ 3.0*vy_ij*y_ij*z_ij*z2_tmp*(z_tmp + a_disk) ) / z2_tmp ;
/* for HALO */
r2 = SQR(b_halo);
r2 += x_ij*x_ij + y_ij*y_ij + z_ij*z_ij; r = sqrt(r2);
rv_ij = vx_ij*x_ij + vy_ij*y_ij + vz_ij*z_ij;
tmp = m_halo / r;
pot_act_ext[i] -= tmp;
tmp /= r2;
a_act_new[i][0] -= tmp * x_ij;
a_act_new[i][1] -= tmp * y_ij;
a_act_new[i][2] -= tmp * z_ij;
adot_act_new[i][0] -= tmp * (vx_ij - 3.0*rv_ij * x_ij/r2);
adot_act_new[i][1] -= tmp * (vy_ij - 3.0*rv_ij * y_ij/r2);
adot_act_new[i][2] -= tmp * (vz_ij - 3.0*rv_ij * z_ij/r2);
} /* i */
#endif
#ifdef EXTPOT_GAL_DEH
for (i=0; i<ni; i++)
@ -1181,7 +896,7 @@ void energy_contr(const double time_cur, const double timesteps, const double n_
double E_pot_ext = 0.0;
#ifdef EXTPOT
for (i=0; i<N; i++) E_pot_ext += m[i]*pot_ext[i];
for (int i=0; i<N; i++) E_pot_ext += m[i]*pot_ext[i];
#endif
if (timesteps == 0.0) { //TODO what is this thing?
@ -1392,32 +1107,9 @@ int main(int argc, char *argv[])
inp_data : name of the input file (data.inp)
*/
/* Normalization... */
#ifdef NORM
inp = fopen("phi-GRAPE.norm","r");
fscanf(inp,"%lE %lE", &m_norm, &r_norm);
fclose(inp);
m_norm *= Msol;
r_norm *= pc;
v_norm = sqrt(G*m_norm/r_norm);
t_norm = (r_norm/v_norm);
#endif // NORM
/* Read the data for EXTernal POTential */
#ifdef EXTPOT
inp = fopen("phi-GRAPE.ext","r");
#ifdef EXTPOT_GAL
fscanf(inp,"%lE %lE %lE", &m_bulge, &a_bulge, &b_bulge);
fscanf(inp,"%lE %lE %lE", &m_disk, &a_disk, &b_disk);
fscanf(inp,"%lE %lE %lE", &m_halo, &a_halo, &b_halo);
m_bulge *= (Msol/m_norm); a_bulge *= (kpc/r_norm); b_bulge *= (kpc/r_norm);
m_disk *= (Msol/m_norm); a_disk *= (kpc/r_norm); b_disk *= (kpc/r_norm);
m_halo *= (Msol/m_norm); a_halo *= (kpc/r_norm); b_halo *= (kpc/r_norm);
#endif
// auto inp = fopen("phi-GRAPE.ext","r");
#ifdef EXTPOT_BH
fscanf(inp,"%lE %lE", &m_bh, &b_bh);
@ -1435,7 +1127,7 @@ int main(int argc, char *argv[])
r2_halo = SQR(r_halo);
#endif
fclose(inp);
// fclose(inp);
#endif // EXTPOT
/* read the global data for particles to the rootRank */
@ -1466,12 +1158,6 @@ int main(int argc, char *argv[])
printf("External Potential: \n");
printf("\n");
#ifdef EXTPOT_GAL
printf("m_bulge = %.4E [Msol] a_bulge = %.4E b_bulge = %.4E [kpc] \n", m_bulge*m_norm/Msol, a_bulge*r_norm/kpc, b_bulge*r_norm/kpc);
printf("m_disk = %.4E [Msol] a_disk = %.4E b_disk = %.4E [kpc] \n", m_disk*m_norm/Msol, a_disk*r_norm/kpc, b_disk*r_norm/kpc);
printf("m_halo = %.4E [Msol] a_halo = %.4E b_halo = %.4E [kpc] \n", m_halo*m_norm/Msol, a_halo*r_norm/kpc, b_halo*r_norm/kpc);
#endif
#ifdef EXTPOT_BH
printf("m_bh = %.4E b_bh = %.4E \n", m_bh, b_bh);
#endif
@ -1541,21 +1227,6 @@ int main(int argc, char *argv[])
#ifdef EXTPOT
#ifdef EXTPOT_GAL
MPI_Bcast(&m_bulge, 1, MPI_DOUBLE, rootRank, MPI_COMM_WORLD);
MPI_Bcast(&a_bulge, 1, MPI_DOUBLE, rootRank, MPI_COMM_WORLD);
MPI_Bcast(&b_bulge, 1, MPI_DOUBLE, rootRank, MPI_COMM_WORLD);
MPI_Bcast(&m_disk, 1, MPI_DOUBLE, rootRank, MPI_COMM_WORLD);
MPI_Bcast(&a_disk, 1, MPI_DOUBLE, rootRank, MPI_COMM_WORLD);
MPI_Bcast(&b_disk, 1, MPI_DOUBLE, rootRank, MPI_COMM_WORLD);
MPI_Bcast(&m_halo, 1, MPI_DOUBLE, rootRank, MPI_COMM_WORLD);
MPI_Bcast(&a_halo, 1, MPI_DOUBLE, rootRank, MPI_COMM_WORLD);
MPI_Bcast(&b_halo, 1, MPI_DOUBLE, rootRank, MPI_COMM_WORLD);
#endif
#ifdef EXTPOT_BH
MPI_Bcast(&m_bh, 1, MPI_DOUBLE, rootRank, MPI_COMM_WORLD);
MPI_Bcast(&b_bh, 1, MPI_DOUBLE, rootRank, MPI_COMM_WORLD);
@ -1580,6 +1251,22 @@ int main(int argc, char *argv[])
/* Wait to all processors to finish his works... */
MPI_Barrier(MPI_COMM_WORLD);
external_gravity.m_bulge = config->ext_m_bulge/config->norm_mass;
external_gravity.b_bulge = config->ext_b_bulge/config->norm_length*1000;
external_gravity.m_disk = config->ext_m_disk/config->norm_mass;
external_gravity.a_disk = config->ext_a_disk/config->norm_length*1000;
external_gravity.b_disk = config->ext_b_disk/config->norm_length*1000;
external_gravity.m_halo = config->ext_m_halo_plummer/config->norm_mass;
external_gravity.b_halo = config->ext_b_halo_plummer/config->norm_length*1000;
if (external_gravity.m_bulge > 0)
printf("m_bulge = %.4E b_bulge = %.4E\n", external_gravity.m_bulge, external_gravity.b_bulge);
if (external_gravity.m_disk > 0)
printf("m_disk = %.4E a_disk = %.4E b_disk = %.4E\n", external_gravity.m_disk, external_gravity.a_disk, external_gravity.b_disk);
if (external_gravity.m_halo > 0)
printf("m_halo = %.4E b_halo = %.4E\n", external_gravity.m_halo, external_gravity.b_halo);
eta_s = eta/ETA_S_CORR;
eta_bh = eta/ETA_BH_CORR;
@ -1636,7 +1323,7 @@ int main(int argc, char *argv[])
/* init the local GRAPE's */
#ifdef MPI_OVERRIDE
numGPU = 1;
numGPU = 1; // TODO get this from config file
clusterid = myRank % numGPU;
#else
MPI_Comm shmcomm;
@ -1816,7 +1503,8 @@ int main(int argc, char *argv[])
}
#ifdef EXTPOT
calc_ext_grav_zero();
// /*/*/*/*/*/*calc_ext_grav_zero();*/*/*/*/*/*/
calc_ext_grav(n_act, x_act, v_act, a, adot);
#endif
/* Wait to all processors to finish his works... */
@ -2223,7 +1911,7 @@ int main(int argc, char *argv[])
}
#ifdef EXTPOT
calc_ext_grav();
calc_ext_grav(n_act, x_act_new, v_act_new, a_act_new, adot_act_new);
#endif
/* correct the active particles positions etc... on all the nodes */