Added spins to config file and got rid of more _act arrays

This commit is contained in:
Yohai Meiron 2020-04-08 20:38:36 -04:00
parent ebec3280f8
commit 75ad0f0e89
4 changed files with 178 additions and 185 deletions

View file

@ -594,80 +594,79 @@ inline double aarseth_step(const double eta, const double dt_tmp, const double3
return sqrt(eta*(a1abs*a2dot1abs+adot1abs*adot1abs)/(adot1abs*a3dot1abs+a2dot1abs*a2dot1abs));
}
void binary_smbh_influence_sphere_output(int i_bh1, int i_bh2, int ind_act[], double m_act[], double3 x_act[], double3 v_act[], double pot_act[], double dt_act[], int n_act, double timesteps, double time_cur, double factor, int inf_event[])
void binary_smbh_influence_sphere_output(int i_bh1, int i_bh2, int ind_act[], int n_act, double timesteps, double time_cur, double factor, int inf_event[], Source_particle_list *source_particle_list)
{
//TODO !!IMPORTANT!! only open the file IF THERE IS ANYTHING TO WRITE!!!
//TODO inf_event to be static or something?
auto out = fopen("bbh_inf.dat", "a");
double m_bh1 = m_act[i_bh1];
double m_bh2 = m_act[i_bh2];
double3 x_bh1 = x_act[i_bh1];
double3 x_bh2 = x_act[i_bh2];
double3 v_bh1 = v_act[i_bh1];
double3 v_bh2 = v_act[i_bh2];
double m_bh1 = source_particle_list->m[0];
double m_bh2 = source_particle_list->m[1];
double3 x_bh1 = source_particle_list->x[0];
double3 x_bh2 = source_particle_list->x[1];
double3 v_bh1 = source_particle_list->v[0];
double3 v_bh2 = source_particle_list->v[1];
double3 x_bbhc = (m_bh1*x_bh1 + m_bh2*x_bh2)/(m_bh1 + m_bh2);
double3 v_bbhc = (m_bh1*v_bh1 + m_bh2*v_bh2)/(m_bh1 + m_bh2);
double DR2 = SQR(x_bh1[0] - x_bh2[0]) + SQR(x_bh1[1] - x_bh2[1]) + SQR(x_bh1[2] - x_bh2[2]);
double DV2 = SQR(v_bh1[0] - v_bh2[0]) + SQR(v_bh1[1] - v_bh2[1]) + SQR(v_bh1[2] - v_bh2[2]);
double DR2 = (x_bh1 - x_bh2).norm2();
double DV2 = (v_bh1 - v_bh2).norm2();
double EB = -(m_bh1 + m_bh2) / sqrt(DR2) + 0.5 * DV2;
double SEMI_a = -0.5 * (m_bh1 + m_bh2)/EB;
double SEMI_a2 = SQR(SEMI_a);
for (int i=2; i<n_act; i++) {
for (int i=0; i<n_act; i++) {
int j_act = ind_act[i];
if (j_act<2) continue;
double tmp_r2 = SQR(x_act[i][0] - x_bbhc[0]) + SQR(x_act[i][1] - x_bbhc[1]) + SQR(x_act[i][2] - x_bbhc[2]);
int iii = ind_act[i];
double& pot_bh1 = source_particle_list->pot[0];
double& pot_bh2 = source_particle_list->pot[1];
double& m_act = source_particle_list->m[j_act];
double3& x_act = source_particle_list->x[j_act];
double3& v_act = source_particle_list->v[j_act];
double& dt_act = source_particle_list->dt[j_act];
double& pot_act = source_particle_list->pot[j_act];
double tmp_r2 = (x_act - x_bbhc).norm2();
if (tmp_r2 < SEMI_a2*SQR(factor)) {
if (inf_event[iii] == 0) {
if (inf_event[j_act] == 0) {
fprintf(out,"INF1 %.6E %.16E %07d %07d %.6E % .6E % .6E % .6E % .6E % .6E % .6E %.6E % .6E % .6E % .6E % .6E % .6E % .6E % .6E %.6E % .6E % .6E % .6E % .6E % .6E % .6E % .6E %.6E %.6E % .6E % .6E % .6E % .6E % .6E % .6E % .6E %.6E \n",
timesteps, time_cur, i, ind_act[i],
timesteps, time_cur, i, j_act,
sqrt(DR2), x_bbhc[0], x_bbhc[1], x_bbhc[2], v_bbhc[0], v_bbhc[1], v_bbhc[2],
m_bh1, x_bh1[0], x_bh1[1], x_bh1[2], v_bh1[0], v_bh1[1], v_bh1[2], pot_act[0],
m_bh2, x_bh2[0], x_bh2[1], x_bh2[2], v_bh2[0], v_bh2[1], v_bh2[2], pot_act[1],
m_bh1, x_bh1[0], x_bh1[1], x_bh1[2], v_bh1[0], v_bh1[1], v_bh1[2], pot_bh1,
m_bh2, x_bh2[0], x_bh2[1], x_bh2[2], v_bh2[0], v_bh2[1], v_bh2[2], pot_bh2,
sqrt(tmp_r2),
m_act[i], x_act[i][0], x_act[i][1], x_act[i][2], v_act[i][0], v_act[i][1], v_act[i][2], pot_act[i],
dt_act[i]);
m_act, x_act[0], x_act[1], x_act[2], v_act[0], v_act[1], v_act[2], pot_act,
dt_act);
inf_event[iii] = 1;
inf_event[j_act] = 1;
}
} else {
if (inf_event[iii] == 1) {
if (inf_event[j_act] == 1) {
fprintf(out,"INF2 %.6E %.16E %07d %07d %.6E % .6E % .6E % .6E % .6E % .6E % .6E %.6E % .6E % .6E % .6E % .6E % .6E % .6E % .6E %.6E % .6E % .6E % .6E % .6E % .6E % .6E % .6E %.6E %.6E % .6E % .6E % .6E % .6E % .6E % .6E % .6E %.6E \n",
timesteps, time_cur, i, ind_act[i],
sqrt(DR2), x_bbhc[0], x_bbhc[1], x_bbhc[2], v_bbhc[0], v_bbhc[1], v_bbhc[2],
m_bh1, x_bh1[0], x_bh1[1], x_bh1[2], v_bh1[0], v_bh1[1], v_bh1[2], pot_act[0],
m_bh2, x_bh2[0], x_bh2[1], x_bh2[2], v_bh2[0], v_bh2[1], v_bh2[2], pot_act[1],
m_bh1, x_bh1[0], x_bh1[1], x_bh1[2], v_bh1[0], v_bh1[1], v_bh1[2], pot_bh1,
m_bh2, x_bh2[0], x_bh2[1], x_bh2[2], v_bh2[0], v_bh2[1], v_bh2[2], pot_bh2,
sqrt(tmp_r2),
m_act[i], x_act[i][0], x_act[i][1], x_act[i][2], v_act[i][0], v_act[i][1], v_act[i][2], pot_act[i],
dt_act[i]);
m_act, x_act[0], x_act[1], x_act[2], v_act[0], v_act[1], v_act[2], pot_act,
dt_act);
}
inf_event[iii] = 0;
inf_event[j_act] = 0;
} /* if (tmp_r2 < DR2*R_INF2) */
} /* i */
fclose(out);
}
void adjust_bsmbh_softening(const double eps, const double eps_bh, const int i_bh1, const int i_bh2, const double m_act[], const double3 x_act_new[], const double3 v_act_new[], double pot_act_new[], double3 a_act_new[], double3 adot_act_new[])
inline void adjust_bsmbh_softening(const double eps, const double eps_bh, const int i_bh1, const int i_bh2, const double m_bh1, const double m_bh2, const double3 x_act_new[], const double3 v_act_new[], double pot_act_new[], double3 a_act_new[], double3 adot_act_new[])
{
double m_bh1 = m_act[i_bh1];
double m_bh2 = m_act[i_bh2];
double3 x_bh1 = x_act_new[i_bh1];
double3 v_bh1 = v_act_new[i_bh1];
@ -767,9 +766,6 @@ int main(int argc, char *argv[])
FILE *out;
double C_NB;
int usedOrNot[7];
double pot_ext[N_MAX], pot_act_ext[N_MAX]; // for all EXTPOT
int i_bh1, i_bh2;
@ -779,9 +775,6 @@ int main(int argc, char *argv[])
int inf_event[N_MAX];
double3 x_bbhc, v_bbhc;
double s_bh1[3] = {0.0, 0.0, 1.0};
double s_bh2[3] = {0.0, 0.0, 1.0};
double3 zeros = {0, 0, 0}; // Dummy; can't really be const because of the GRAPE interface.
/* INIT the rand() !!! */
@ -808,8 +801,6 @@ int main(int argc, char *argv[])
/* read the input parameters to the rootRank */
config = new Config("phigrape.conf");
C_NB = config->pn_c;
std::copy(config->pn_usage.begin(), config->pn_usage.end(), usedOrNot);
if (is_hdf5(config->input_file_name)) {
#ifndef HAS_HDF5
@ -1006,10 +997,10 @@ int main(int argc, char *argv[])
/* load the nj particles to the G6 */
for (int j=0; j<n_loc; j++) {
int kkk = j + myRank*n_loc;
g6_set_j_particle(clusterid, j, ind[kkk], t[kkk], dt[kkk], m[kkk], zeros, zeros, zeros, v[kkk], x[kkk]);
} /* j */
for (int k=0; k<n_loc; k++) {
int j = k + myRank*n_loc;
g6_set_j_particle(clusterid, k, ind[j], t[j], dt[j], m[j], zeros, zeros, zeros, v[j], x[j]);
} /* k */
#ifdef ETICS
double etics_length_scale;
@ -1124,13 +1115,11 @@ int main(int argc, char *argv[])
// calculate and "plus" the new BH <-> BH : PN1, PN2, PN2.5, PN3, PN3.5 : acc, jerk
dt_bh_tmp = dt[0];
tmp_i = calc_force_pn_BH(m_bh1, x_bh1, v_bh1, s_bh1,
m_bh2, x_bh2, v_bh2, s_bh2,
C_NB, dt_bh_tmp, usedOrNot,
(double(*)[3])a_pn1, (double(*)[3])adot_pn1,
(double(*)[3])a_pn2, (double(*)[3])adot_pn2, myRank, rootRank);
tmp_i = calc_force_pn_BH(m[i_bh1], x[i_bh1], v[i_bh1], config->smbh1_spin.data(),
m[i_bh2], x[i_bh2], v[i_bh2], config->smbh2_spin.data(),
config->pn_c, dt[i_bh1], config->pn_usage.data(),
(double(*)[3])a_pn1, (double(*)[3])adot_pn1,
(double(*)[3])a_pn2, (double(*)[3])adot_pn2, myRank, rootRank);
a[i_bh1] += a_pn1[1] + a_pn1[2] + a_pn1[3] + a_pn1[4] + a_pn1[5] + a_pn1[6];
a[i_bh2] += a_pn2[1] + a_pn2[2] + a_pn2[3] + a_pn2[4] + a_pn2[5] + a_pn2[6];
@ -1187,14 +1176,12 @@ int main(int argc, char *argv[])
/* Define initial timestep for all particles on all nodes */
for (int i=0; i<N; i++) {
a2_mod = a[i][0]*a[i][0]+a[i][1]*a[i][1]+a[i][2]*a[i][2];
adot2_mod = adot[i][0]*adot[i][0]+adot[i][1]*adot[i][1]+adot[i][2]*adot[i][2];
for (int j=0; j<N; j++) {
a2_mod = a[j].norm2();
adot2_mod = adot[j].norm2();
if (adot2_mod == 0)
dt_tmp = eta_s;
else
dt_tmp = eta_s*sqrt(a2_mod/adot2_mod);
if (adot2_mod==0) dt_tmp = eta_s; // That's weird, when will we have such a case?
else dt_tmp = eta_s*sqrt(a2_mod/adot2_mod);
power = log(dt_tmp)/log(2.0) - 1;
@ -1203,15 +1190,15 @@ int main(int argc, char *argv[])
if (dt_tmp < dt_min) dt_tmp = dt_min;
if (dt_tmp > dt_max) dt_tmp = dt_max;
dt[i] = dt_tmp;
dt[j] = dt_tmp;
if (config->dt_min_warning && (myRank == 0)) {
if (dt[i] == dt_min) {
printf("!!! Warning0: dt = dt_min = %.6E \t ind = %07d \n", dt[i], ind[i]);
if (dt[j] == dt_min) {
printf("!!! Warning0: dt = dt_min = %.6E \t ind = %07d \n", dt[j], ind[j]);
fflush(stdout);
}
}
} /* i */
} /* j */
if (config->live_smbh_count > 0) {
double min_dt = *std::min_element(dt, dt+N);
@ -1224,10 +1211,10 @@ int main(int argc, char *argv[])
/* load the new values for particles to the local GRAPE's */
/* load the nj particles to the G6 */
for (int j=0; j<n_loc; j++) {
int kkk = j + myRank*n_loc;
g6_set_j_particle(clusterid, j, ind[kkk], t[kkk], dt[kkk], m[kkk], zeros, adot[kkk]*(1./6.), a[kkk]*0.5, v[kkk], x[kkk]);
} /* j */
for (int k=0; k<n_loc; k++) {
int j = k + myRank*n_loc;
g6_set_j_particle(clusterid, k, ind[j], t[j], dt[j], m[j], zeros, adot[j]*(1./6.), a[j]*0.5, v[j], x[j]);
} /* k */
if (myRank == rootRank) {
@ -1345,16 +1332,16 @@ int main(int argc, char *argv[])
for (int i=0; i<n_act; i++) {
int j_act = ind_act[i];
// NOTICE much of these are just not needed!
m_act[i] = m[j_act];
x_act[i] = x[j_act];
v_act[i] = v[j_act];
// m_act[i] = m[j_act];
// x_act[i] = x[j_act];
// v_act[i] = v[j_act];
t_act[i] = t[j_act];
dt_act[i] = dt[j_act];
//dt_act[i] = dt[j_act];
// NOTICE Why do we need pot_act and pot_act_ext? Probably redundant.
pot_act[i] = pot[j_act];
pot_act_ext[i] = pot_ext[j_act];
a_act[i] = a[j_act];
adot_act[i] = adot[j_act];
//pot_act[i] = pot[j_act];
pot_act_ext[i] = pot_ext[j_act]; // TODO almost certainly redundant
a_act[i] = a[j_act]; // TODO is used by calculate_high_derivatives, but should try to avoid!
adot_act[i] = adot[j_act]; // TODO is used by calculate_high_derivatives, but should try to avoid!
} /* i */
#ifdef TIMING
@ -1369,11 +1356,12 @@ int main(int argc, char *argv[])
#endif
for (int i=0; i<n_act; i++) {
dt_tmp = min_t - t_act[i];
dt2half = 0.5*dt_tmp*dt_tmp;
dt3over6 = (1./3.)*dt_tmp*dt2half;
x_act_new[i] = x_act[i] + v_act[i]*dt_tmp + a_act[i]*dt2half + adot_act[i]*dt3over6;
v_act_new[i] = v_act[i] + a_act[i]*dt_tmp + adot_act[i]*dt2half;
int j_act = ind_act[i];
double dt = min_t - t[j_act];
dt2half = 0.5*dt*dt;
dt3over6 = (1./3.)*dt*dt2half;
x_act_new[i] = x[j_act] + v[j_act]*dt + a[j_act]*dt2half + adot[j_act]*dt3over6;
v_act_new[i] = v[j_act] + a[j_act]*dt + adot[j_act]*dt2half;
} /* i */
#ifdef TIMING
@ -1409,17 +1397,15 @@ int main(int argc, char *argv[])
if (config->live_smbh_count == 2) {
if (config->live_smbh_custom_eps >= 0) {
adjust_bsmbh_softening(eps, config->live_smbh_custom_eps, i_bh1, i_bh2, m_act, x_act_new, v_act_new, pot_act_new, a_act_new, adot_act_new);
adjust_bsmbh_softening(eps, config->live_smbh_custom_eps, i_bh1, i_bh2, m[0], m[1], x_act_new, v_act_new, pot_act_new, a_act_new, adot_act_new);
}
if (config->binary_smbh_pn) {
// calculate and "plus" the new BH <-> BH : PN1, PN2, PN2.5, PN3, PN3.5 : acc, jerk
dt_bh_tmp = dt[0];
tmp_i = calc_force_pn_BH(m_bh1, x_act_new[i_bh1], v_act_new[i_bh1], s_bh1,
m_bh2, x_act_new[i_bh2], v_act_new[i_bh2], s_bh2,
C_NB, dt_bh_tmp, usedOrNot,
tmp_i = calc_force_pn_BH(m[0], x_act_new[i_bh1], v_act_new[i_bh1], config->smbh1_spin.data(),
m[1], x_act_new[i_bh2], v_act_new[i_bh2], config->smbh2_spin.data(),
config->pn_c, dt[i_bh1], config->pn_usage.data(),
(double(*)[3])a_pn1, (double(*)[3])adot_pn1,
(double(*)[3])a_pn2, (double(*)[3])adot_pn2, myRank, rootRank);
@ -1447,6 +1433,7 @@ int main(int argc, char *argv[])
get_CPU_time(&CPU_tmp_real0, &CPU_tmp_user0, &CPU_tmp_syst0);
#endif
double min_dt = dt_max;
for (int i=0; i<n_act; i++) {
// NOTICE looks like we're doing three unrelated things in this loop: (1) correcting positions and velocities (2) calculating new steps, and (3) putting the corrected values from the _act_new back in the _act arrays.
// After going back to the _act arrays they don't do much before they go back to the main arrays, so this copy seems redundant (the SMBH influence sphere printout needs these values but it should be a function anyway).
@ -1458,7 +1445,6 @@ int main(int argc, char *argv[])
corrector(dt_tmp, a2, a3, &x_act_new[i], &v_act_new[i]);
//TODO make beautiful
double eta_curr;
if ((config->live_smbh_count > 0) && (ind_act[i] < config->live_smbh_count)) eta_curr = eta_bh;
@ -1468,7 +1454,6 @@ int main(int argc, char *argv[])
//TODO the below should be moved to a function
if (dt_new < dt_min) dt_tmp = dt_min;
if ((dt_new < dt_tmp) && (dt_new > dt_min)) {
power = log(dt_new)/log(2.0) - 1;
dt_tmp = pow(2.0, (double)power); // TODO why is this casting needed here?
@ -1479,63 +1464,37 @@ int main(int argc, char *argv[])
}
if (config->dt_min_warning && (myRank == 0)) {
if (dt_act[i] == dt_min) {
printf("!!! Warning1: dt_act = dt_min = %.6E \t ind_act = %07d \n", dt[i], ind_act[i]);
if (dt_tmp == dt_min) {
printf("!!! Warning1: dt_act = dt_min = %.6E \t ind_act = %07d \n", dt_tmp, ind_act[i]);
fflush(stdout);
}
}
if (dt_tmp < min_dt) min_dt = dt_tmp;
/* BEGIN copy of everything */
dt_act[i] = dt_tmp;
t_act[i] = min_t;
pot_act[i] = pot_act_new[i];
x_act[i] = x_act_new[i];
v_act[i] = v_act_new[i];
a_act[i] = a_act_new[i];
adot_act[i] = adot_act_new[i];
/* END copy of everything */
int j_act = ind_act[i];
x[j_act] = x_act_new[i];
v[j_act] = v_act_new[i];
t[j_act] = min_t;
dt[j_act] = dt_tmp;
pot[j_act] = pot_act_new[i];
pot_ext[j_act] = pot_act_ext[i]; // ???
a[j_act] = a_act_new[i];
adot[j_act] = adot_act_new[i];
} /* i */
/* define the min. dt over all the act. part. and set it also for the BH... */
if (config->live_smbh_count > 0) {
double min_dt = *std::min_element(dt_act, dt_act+n_act);
if (config->live_smbh_count>=1) dt_act[i_bh1] = min_dt;
if (config->live_smbh_count==2) dt_act[i_bh2] = min_dt;
if (config->live_smbh_count>=1) dt[0] = min_dt;
if (config->live_smbh_count==2) dt[1] = min_dt;
}
if (config->binary_smbh_influence_sphere_output && (myRank == rootRank)) {
//TODO clean up this mass. We don't want to have all these _act arrays; they are only needed for this lame function.
binary_smbh_influence_sphere_output(i_bh1, i_bh2, ind_act, m_act, x_act_new, v_act_new, pot_act_new, dt_act, n_act, timesteps, time_cur, config->binary_smbh_influence_radius_factor, inf_event);
binary_smbh_influence_sphere_output(i_bh1, i_bh2, ind_act, n_act, timesteps, time_cur, config->binary_smbh_influence_radius_factor, inf_event, &source_particle_list);
}
/* Return back the new coordinates + etc... of active part. to the global data... */
for (int i=0; i<n_act; i++) {
iii = ind_act[i];
m[iii] = m_act[i];
x[iii] = x_act[i];
v[iii] = v_act[i];
t[iii] = t_act[i];
dt[iii] = dt_act[i];
pot[iii] = pot_act[i];
pot_ext[iii] = pot_act_ext[i];
a[iii] = a_act[i];
adot[iii] = adot_act[i];
} /* i */
#ifdef TIMING
get_CPU_time(&CPU_tmp_real, &CPU_tmp_user, &CPU_tmp_syst);
DT_ACT_CORR += (CPU_tmp_user - CPU_tmp_user0);
@ -1554,10 +1513,10 @@ int main(int argc, char *argv[])
cur_rank = ind_act[i]/n_loc;
if (myRank == cur_rank) {
int j_act = ind_act[i];
jjj = ind_act[i] - myRank*n_loc;
g6_set_j_particle(clusterid, jjj, ind_act[i], t_act[i], dt_act[i], m_act[i], zeros, adot_act[i]*(1./6.), a_act[i]*0.5, v_act[i], x_act[i]);
g6_set_j_particle(clusterid, jjj, ind_act[i], t[j_act], dt[j_act], m[j_act], zeros, adot[j_act]*(1./6.), a[j_act]*0.5, v[j_act], x[j_act]);
} /* if (myRank == cur_rank) */