2 #include "Common/binary_tree.h"
11 static double RayleighDistribution(
const double sigma){
13 static bool first =
true;
15 mt.init_genrand( PS::Comm::getRank() );
18 double F = mt.genrand_res53();
26 return sqrt( -2.0*sigma*sigma*log(1.0-F));
32 static double HayashiDistribution(
const double a_in,
const double a_out){
34 static bool first =
true;
36 mt.init_genrand( PS::Comm::getRank() );
39 const double C = 0.5 / (sqrt(a_out) - sqrt(a_in));
40 double P = mt.genrand_res53();
41 double ret = P/(2*C) + sqrt(a_in);
49 static double HayashiDistributionWithIceLine(
const double a_in,
const double a_out,
50 const double a_ice,
const double f_ice=1.0,
const double p_sigma=-1.5){
53 const PS::F64 p_mass = 2.0 + p_sigma;
57 static bool first =
true;
61 mt.init_genrand( PS::Comm::getRank() );
65 double P = mt.genrand_res53();
69 if(a_ice <= a_in || a_ice >= a_out){
71 C = p_mass / (pow(a_out, p_mass) - pow(a_in, p_mass));
72 ret = pow(P*p_mass/C + pow(a_in, p_mass), 1.0/p_mass);
76 C = p_mass / ( f_ice*(pow(a_out, p_mass)-pow(a_ice, p_mass)) + pow(a_ice, p_mass) - pow(a_in, p_mass) );
77 P_ice = C/p_mass*(pow(a_ice, p_mass) - pow(a_in, p_mass));
81 ret = pow(P*p_mass/C + pow(a_in, p_mass), 1.0/p_mass);
84 ret = pow( ((P*p_mass/C + pow(a_in, p_mass) - pow(a_ice, p_mass))/f_ice + pow(a_ice, p_mass)), 1.0/p_mass);
91 static double AU2CM(
const double x){
92 return x * 1.49597871e13;
95 static double CM2AU(
const double x){
96 return x / 1.49597871e13;
115 const long long int n_glb,
116 const long long int n_loc,
121 const double dens = 10.0,
122 const double mass_sun = 1.0,
123 const double a_ice = 0.0,
124 const double f_ice = 1.0,
125 const double power = -1.5,
127 const double gravitational_constant = 1.0
129 static const double mass_sun_gram = 1.989e33;
132 mt.init_genrand( PS::Comm::getRank()+seed*PS::Comm::getNumberOfProc() );
133 static const double PI = atan(1.0) * 4.0;
134 const double AU = AU2CM(1.0);
136 mass_planet_glb = 2.0 * PI * dens / (2.0+power) * ( pow(a_out, 2.0+power) - pow(a_in, 2.0+power) ) * AU * AU / mass_sun_gram;
137 const double m_planet = mass_planet_glb / n_glb;
138 mass =
new double[n_loc];
141 const double h = pow(2.0*m_planet / (3.0*mass_sun), 1.0/3.0);
143 const PS::F64 e_sigma = sqrt(0.5*e_rms*e_rms);
144 const PS::F64 i_sigma = sqrt(0.5*i_rms*i_rms);
147 for(
long long int i=0; i<n_loc; i++){
150 bin.semi = HayashiDistributionWithIceLine(a_in, a_out, a_ice, f_ice, power);
151 bin.ecc = RayleighDistribution(e_sigma) * h;
152 bin.incline = RayleighDistribution(i_sigma) * h;
153 bin.rot_horizon = 2.0 * PI * mt.genrand_res53();
154 bin.rot_self = 2.0 * PI * mt.genrand_res53();
155 double l = 2.0 * PI * mt.genrand_res53();
156 bin.ecca = bin.calcEccAnomaly(l, bin.ecc);
160 bin.calcParticles(sun, planet, gravitational_constant);
163 e_ave += bin.ecc*bin.ecc;
165 PS::F64 e_ave_glb = sqrt(PS::Comm::getSum(e_ave)/n_glb);
166 if(PS::Comm::getRank() == 0){
167 std::cerr<<
"e_ave_glb="<<e_ave_glb<<std::endl;
168 std::cerr<<
"e_ave_hill="<<e_ave_glb/h<<std::endl;
169 std::cerr<<
"e_rms="<<e_rms<<std::endl;
174 const long long int n_glb,
175 const long long int n_loc,
179 const double eng = -0.25,
183 static const double PI = atan(1.0) * 4.0;
184 const double r_cutoff = 22.8 / (-3.0 * PI * mass_glb * mass_glb / (64.0 * -0.25));
186 mass =
new double[n_loc];
191 mt.init_genrand( PS::Comm::getRank() );
192 for(
int i=0; i<n_loc; i++){
193 mass[i] = mass_glb / n_glb;
194 double r_tmp = 9999.9;
195 while(r_tmp > r_cutoff){
196 double m_tmp = mt.genrand_res53();
197 r_tmp = 1.0 / sqrt( pow(m_tmp, (-2.0/3.0)) - 1.0);
199 double phi = 2.0 * PI * mt.genrand_res53();
200 double cth = 2.0 * (mt.genrand_real2() - 0.5);
201 double sth = sqrt(1.0 - cth*cth);
202 pos[i][0] = r_tmp * sth * cos(phi);
203 pos[i][1] = r_tmp * sth * sin(phi);
204 pos[i][2] = r_tmp * cth;
206 const double v_max = 0.1;
207 const double v_try = mt.genrand_res53();
208 const double v_crit = v_max * mt.genrand_res53();
209 if(v_crit < v_try * v_try * pow( (1.0 - v_try * v_try), 3.5) ){
210 const double ve = sqrt(2.0) * pow( (r_tmp*r_tmp + 1.0), -0.25 );
211 phi = 2.0 * PI * mt.genrand_res53();
212 cth = 2.0 * (mt.genrand_res53() - 0.5);
213 sth = sqrt(1.0 - cth*cth);
214 vel[i][0] = ve * v_try * sth * cos(phi);
215 vel[i][1] = ve * v_try * sth * sin(phi);
216 vel[i][2] = ve * v_try * cth;
224 double cm_mass = 0.0;
225 for(
PS::S32 i=0; i<n_loc; i++){
226 cm_pos += mass[i] * pos[i];
227 cm_vel += mass[i] * vel[i];
232 for(
PS::S32 i=0; i<n_loc; i++){
237 const double r_scale = -3.0 * PI * mass_glb * mass_glb / (64.0 * eng);
238 const double coef = 1.0 / sqrt(r_scale);
239 for(
PS::S32 i=0; i<n_loc; i++){
244 double r_max_sq = -1.0;
245 for(
int i=0; i<n_loc; i++){
246 if(r_max_sq < pos[i] * pos[i]){
247 r_max_sq = pos[i] * pos[i];