PeTar
N-body code for collisional gravitational systems
two_body_tide.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Common/Float.h"
4 #include "Common/binary_tree.h"
5 
7 
9 class TwoBodyTide{
10 public:
12  Float speed_of_light; // should have the same unit set as that of G
13 
15 
17 
19  bool checkParams() {
22  return true;
23  }
24 
26 
30  template <class TBinary>
31  bool evolveOrbitHyperbolicGW(TBinary& _bin, Float& _Etid, Float& _Ltid) {
32  // calculate energy loss (Hansen 1972, PRD, 5, 1021; correction from Turner 1977, ApJ, 216, 610)
33 
34  Float e = _bin.ecc;
35  Float a = _bin.semi;
36  Float m1 = _bin.m1;
37  Float m2 = _bin.m2;
38 
39  ASSERT(e>1.0);
40  ASSERT(m1>0);
41  ASSERT(m2>0);
42  ASSERT(a<0);
43 
44  Float c = speed_of_light;
45  Float c2 = c*c;
46  Float c5 = c2*c2*c;
47 
48  Float e2 = e*e;
49  Float theta0 = acos(1/e);
50  Float ge = (COMM::PI - theta0) * (96.0 + 292*e2 + 37*e2*e2) + sqrt(e2 - 1)/3.0 * (602.0 + 673*e2);
51 
52  Float mtot = m1 + m2;
53  Float m12 = m1 * m2;
54  Float m12sq = m12*m12;
55  Float p = a * (1 - e2);
56  Float G_over_r = gravitational_constant/p;
57  Float G_over_r3 = G_over_r * G_over_r * G_over_r;
58  Float G_over_r7 = G_over_r3 * G_over_r3 * G_over_r;
59  Float Etid = 2.0 * sqrt(G_over_r7 * mtot) * m12sq * ge / (15.0 * c5);
60 
61  // calculate the angular momentum loss (Hansen 1972)
62  ge = (COMM::PI - theta0) * (8.0 + 7*e2) + sqrt(e2 - 1) * (13 + 2*e2);
63  Float Ltid = 8.0 * G_over_r3 * p * m12sq * ge / (15.0 * c5);
64 
65 
66  // update binary orbit
67  // update semi
68  Float GM12 = gravitational_constant * m12;
69  Float Ebin = - GM12 / (2.0 * a);
70  Float Ebin_new = Ebin - Etid;
71  Float semi_new = - GM12 / (2.0 * Ebin_new);
72 
73  // update ecc
74  Float mfac = GM12 * m12 / mtot;
75  Float Lbin = sqrt(mfac * p);
76  Float Lbin_new = Lbin - Ltid;
77  Float ecc2_new = 1.0 - Lbin_new*Lbin_new / (mfac*_bin.semi);
78 
79  _Etid = Etid;
80  _Ltid = Ltid;
81 
82  ASSERT(Lbin_new>=0);
83  if (ecc2_new < 0) return true;
84 
85  _bin.semi = semi_new;
86  _bin.ecc = sqrt(ecc2_new);
87 
88  return false;
89  }
90 
92 
101  template <class TBinary>
102  Float evolveOrbitDynamicalTide(TBinary& _bin, const Float& rad1, const Float& rad2, const Float& poly_type1, const Float& poly_type2) {
103  ASSERT(_bin.getMemberN()==2);
104  //ASSERT(_bin.semi<0);
105  //ASSERT(_bin.ecc>1);
106 
107  ASSERT(_bin.m1>0);
108  ASSERT(_bin.m2>0);
109  ASSERT(poly_type1==1.5||poly_type1==3.0);
110  ASSERT(poly_type2==1.5||poly_type2==3.0);
111 
112  if (_bin.ecc<0.1) return 0.0; // no tide effect when ecc is low
113 
114  Float peri = _bin.semi * (1.0 - _bin.ecc);
115  ASSERT(peri>rad1+rad2);
116 
117  //Float rad1 = _bse_manager.getStellarRadius(p1->star);
118  //Float rad2 = _bse_manager.getStellarRadius(p2->star);
119  Float mtot = _bin.m1 + _bin.m2;
120 
121  // Press & Taukolsky 1977
122  Float p_over_r1 = peri / rad1;
123  Float p_over_r2 = peri / rad2;
124  Float r1_over_peri = 1.0 / p_over_r1;
125  Float r2_over_peri = 1.0 / p_over_r2;
126  Float eta1 = sqrt(_bin.m1 / mtot * p_over_r1 * p_over_r1 * p_over_r1);
127  Float eta2 = sqrt(_bin.m2 / mtot * p_over_r2 * p_over_r2 * p_over_r2);
128 
129  // Mardling & Aarseth 2001
130  Float mard = 0.5 * fabs(eta1 - 2.);
131  mard = (0.5 + 0.25 * sqrt(mard * mard * mard));
132  Float neweta1 = eta1 * pow(2.0 / (1.0 + _bin.ecc), mard);
133 
134  mard = 0.5 * fabs(eta2 - 2.);
135  mard = (0.5 + 0.25 * sqrt(mard * mard * mard));
136  Float neweta2 = eta2 * pow(2. / (1.0 + _bin.ecc), mard);
137 
138  Float Etid = 0;
139 
140  // TIDE ON 1
141  if ((eta1 > 0) & (eta1 < 10) & (neweta1 > 0) & (neweta1 < 10)) {
142  Etid += calcEtidPolynomicalFit(_bin.m2, r1_over_peri, peri, neweta1, poly_type1);
143  }
144 
145  // TIDE ON 2
146  if ((eta2 > 0) & (eta2 < 10) & (neweta2 > 0) & (neweta2 < 10)) {
147  Etid += calcEtidPolynomicalFit(_bin.m1, r2_over_peri, peri, neweta2, poly_type2);
148  }
149 
150  // assuming angular momentum conserved, the semi-latus rectum is also conserved
151  Float pold = _bin.semi *(1.0 - _bin.ecc*_bin.ecc);
152 
153  // update binary orbit
154  // update semi
155  Float GM12 = gravitational_constant * _bin.m1 * _bin.m2;
156  Float Ebin = - GM12 / (2.0 * _bin.semi);
157  Float Ebin_new = Ebin - Etid;
158  _bin.semi = - GM12 / (2.0 * Ebin_new);
159 
160  // use semi-latus rectum to update ecc
161  _bin.ecc = sqrt(1.0 - pold/_bin.semi);
162  ASSERT(_bin.ecc>=0.0);
163  //_bin.calcParticles(gravitational_constant);
164  //p1->pos += _bin.pos;
165  //p2->pos += _bin.pos;
166  //p1->vel += _bin.vel;
167  //p2->vel += _bin.vel;
168 
169  return Etid;
170  }
171 
173 
180  Float calcEtidPolynomicalFit(const Float& _mpert, const Float& _rad_over_peri, const Float& _peri, const Float& _eta, const Float& _poly_type) {
181  // Tidal fits from Portegies Zwart et al. 1993
182  Float fA=0, fB=0, fC=0, fD=0, fE=0, fF=0;
183  if (_poly_type == 1.5) {
184  fA = -0.397;
185  fB = 1.678;
186  fC = 1.277;
187  fD = -12.42;
188  fE = 9.446;
189  fF = -5.550;
190  }
191  else if (_poly_type == 3.0) {
192  fA = -1.124;
193  fB = 0.877;
194  fC = -13.37;
195  fD = 21.55;
196  fE = -16.8;
197  fF = 4.124;
198  }
199  else {
200  std::cerr<<"Error, polynomical types should be 1.5, 3.0, given "<<_poly_type<<std::endl;
201  abort();
202  }
203 
204  // Tidal energy
205  Float r_over_p2 = _rad_over_peri * _rad_over_peri;
206  Float r_over_p5 = r_over_p2 * r_over_p2 * _rad_over_peri;
207  Float etid = gravitational_constant * r_over_p5 * _mpert * _mpert / _peri;
208 
209  // Now computing T(eta)
210  if (_eta < 1) { // most likely a disruptive encounter
211  etid *= pow(10, fA);
212  } else if (_eta < 10) {
213  Float let = log10(_eta);
214  etid *= pow(10, fA + let * (fB + let * (fC + let * (fD + let * (fE + let * fF)))));
215  }
216 
217  return etid;
218  }
219 
220 };
TidalTensor::getParticleN
static PS::S32 getParticleN()
get particle number
Definition: tidal_tensor.hpp:435
EPISoft
Definition: soft_ptcl.hpp:271
TwoBodyTide::gravitational_constant
Float gravitational_constant
Definition: two_body_tide.hpp:11
TidalTensor::createTidalTensorMeasureParticles
static void createTidalTensorMeasureParticles(Tptcl *_ptcl_tt, const Tptcl &_ptcl_cm, const PS::F64 _size)
create tidal tensor measurement particles
Definition: tidal_tensor.hpp:51
printAcc
void printAcc(FPSoft *ptcl, FPSoft &pcm, int n, TidalTensor &tt)
Definition: tidal_tensor_test.cxx:35
Particle::pos
PS::F64vec3 pos
Definition: tide_test.cxx:20
TwoBodyTide::checkParams
bool checkParams()
check whether parameters values are correct
Definition: two_body_tide.hpp:19
FPSoft
Definition: soft_ptcl.hpp:26
FPSoft::copyFromForce
void copyFromForce(const ForceSoft &force)
Definition: soft_ptcl.hpp:84
EPJSoft::mass
PS::F64 mass
Definition: soft_ptcl.hpp:314
TwoBodyTide::evolveOrbitHyperbolicGW
bool evolveOrbitHyperbolicGW(TBinary &_bin, Float &_Etid, Float &_Ltid)
evolve hyperbolic orbit based on GW effect
Definition: two_body_tide.hpp:31
soft_ptcl.hpp
ParticleBase
Basic particle class.
Definition: particle_base.hpp:20
Particle
A sample particle class.
Definition: tide_test.cxx:16
ForceSoft
Definition: soft_ptcl.hpp:4
PIKG::F64vec
Vector3< F64 > F64vec
Definition: pikg_vector.hpp:167
EPISoft::pos
PS::F64vec pos
Definition: soft_ptcl.hpp:274
Particle::readAscii
void readAscii(std::istream &_fin)
read class data to file with ASCII format
Definition: tide_test.cxx:59
GalpyManager::initial
void initial(const IOParamsGalpy &_input, const double _time, const std::string _conf_name, const bool _restart_flag, const bool _print_flag=false)
initialization function
Definition: galpy_interface.h:852
two_body_tide.hpp
FPSoft::pot_tot
PS::F64 pot_tot
Definition: soft_ptcl.hpp:32
PIKG::F64
double F64
Definition: pikg_vector.hpp:17
Particle::writeBinary
void writeBinary(FILE *_fout) const
write class data to file with binary format
Definition: tide_test.cxx:26
GalpyManager::calcAccPot
void calcAccPot(double *acc, double &pot, const double _time, const double gm, const double *pos_g, const double *pos_l)
calculate acceleration and potential at give position
Definition: galpy_interface.h:1603
IOParamsGalpy::print_flag
bool print_flag
Definition: galpy_interface.h:28
main
int main(int argc, char **argv)
Definition: tidal_tensor_test.cxx:67
TidalTensor::fit
void fit(Tptcl *_ptcl_tt, Tptcl &_ptcl_cm, const PS::F64 _size)
tidal tensor fitting function,
Definition: tidal_tensor.hpp:128
TidalTensor::print
void print(std::ostream &_fout, const int _width) const
Definition: tidal_tensor.hpp:371
TwoBodyTide
Two Body Tide effct.
Definition: two_body_tide.hpp:9
EPISoft::id
PS::S64 id
Definition: soft_ptcl.hpp:273
GalpyManager
A class to manager the API to Galpy.
Definition: galpy_interface.h:658
ParticleBase::pos
PS::F64vec pos
Definition: particle_base.hpp:24
TwoBodyTide::TwoBodyTide
TwoBodyTide()
Definition: two_body_tide.hpp:14
FPSoft::acc
PS::F64vec acc
Definition: soft_ptcl.hpp:28
TwoBodyTide::speed_of_light
Float speed_of_light
Definition: two_body_tide.hpp:12
EPISoft::r_search
PS::F64 r_search
Definition: soft_ptcl.hpp:275
Particle::mass
Float mass
Definition: tide_test.cxx:19
galpy_interface.h
Particle::printColumnTitle
static void printColumnTitle(std::ostream &_fout, const int _width=20)
print titles of class members using column style
Definition: tide_test.cxx:69
TidalTensor::subtractCMForce
static void subtractCMForce(Tptcl *_ptcl_tt, const Tptcl &_ptcl_cm)
subtract c.m. force from measure points
Definition: tidal_tensor.hpp:94
TwoBodyTide::evolveOrbitDynamicalTide
Float evolveOrbitDynamicalTide(TBinary &_bin, const Float &rad1, const Float &rad2, const Float &poly_type1, const Float &poly_type2)
evolve two-body orbit based on dynamical tide implementation from Alessandro Alberto Trani
Definition: two_body_tide.hpp:102
TidalTensor
Tidal tensor perterbation for AR.
Definition: tidal_tensor.hpp:4
EPJSoft
Definition: soft_ptcl.hpp:311
Particle::id
long long int id
Definition: tide_test.cxx:18
FPSoft::pot_soft
PS::F64 pot_soft
Definition: soft_ptcl.hpp:33
EPJSoft::pos
PS::F64vec pos
Definition: soft_ptcl.hpp:315
IOParamsGalpy::read
int read(int argc, char *argv[], const int opt_used_pre=0)
reading parameters from GNU option API
Definition: galpy_interface.h:49
EPJSoft::id
PS::S64 id
Definition: soft_ptcl.hpp:313
EPISoft::eps
static PS::F64 eps
Definition: soft_ptcl.hpp:281
TidalTensor::eval
void eval(PS::F64 *acc, const PS::F64vec &pos) const
Definition: tidal_tensor.hpp:289
IOParamsGalpy
IO parameters for Galpy manager.
Definition: galpy_interface.h:15
ParticleBase::mass
PS::F64 mass
Definition: particle_base.hpp:23
GroupDataDeliver::artificial
ArtificialParticleInformation artificial
Definition: ptcl.hpp:18
Particle::vel
PS::F64vec3 vel
Definition: tide_test.cxx:21
Particle::writeAscii
void writeAscii(std::ostream &_fout) const
write class data to file with ASCII format
Definition: tide_test.cxx:46
static_variables.hpp
TwoBodyTide::calcEtidPolynomicalFit
Float calcEtidPolynomicalFit(const Float &_mpert, const Float &_rad_over_peri, const Float &_peri, const Float &_eta, const Float &_poly_type)
Tidal energy based on Polynomical fits from Portegies Zwart et al. 1993.
Definition: two_body_tide.hpp:180
ArtificialParticleInformation::setParticleTypeToSingle
void setParticleTypeToSingle()
set particle type to single
Definition: artificial_particles.hpp:78
Particle::printColumn
void printColumn(std::ostream &_fout, const int _width=20)
print data of class members using column style
Definition: tide_test.cxx:84
ASSERT
#define ASSERT(expr)
Definition: hard_assert.hpp:238
main
int main(int argc, char **argv)
Definition: tide_test.cxx:96
PIKG::F64vec3
Vector3< F64 > F64vec3
Definition: pikg_vector.hpp:169
PRINT_WIDTH
#define PRINT_WIDTH
Definition: io.hpp:10
ParticleBase::printTitleWithMeaning
static int printTitleWithMeaning(std::ostream &_fout, const int _counter=0, const int _offset=0)
print column title with meaning (each line for one column)
Definition: particle_base.hpp:243
tidal_tensor.hpp
Particle::readBinary
void readBinary(FILE *_fin)
read class data to file with binary format
Definition: tide_test.cxx:34
Ptcl::group_data
GroupDataDeliver group_data
Definition: ptcl.hpp:40
CalcForceEpSpMonoNoSimd
Definition: soft_force.hpp:125
ParticleBase::readAscii
void readAscii(FILE *fp)
read class data with ASCII format
Definition: particle_base.hpp:161
soft_force.hpp
ForceSoft::grav_const
static PS::F64 grav_const
neighbor number+1
Definition: soft_ptcl.hpp:15