Planetary Orbital Evolution due to Tides
Orbital evolution of two objects experiencing tides
EccentricityExpansionCoefficients.cpp
1 #define BUILDING_LIBRARY
3 
4 namespace Evolve {
5 
7  int s,
8  int epower) const
9  {
10  assert(std::abs(msign) < 2);
11 
12  return (epower - s + 2 * std::min(msign, s - msign)) / 2;
13  }
14 
15  std::pair<double, double> EccentricityExpansionCoefficients::p_m2s(
16  double e,
17  int s,
18  unsigned max_e_power,
19  bool deriv
20  ) const
21  {
22  std::pair<double, double> result(0.0, 0.0);
23 
24  double e2 = std::pow(e, 2);
25  int min_n = std::max(1, -s - 1),
26  gamma_ind1 = s + __max_e_power + 2,
27  e_pow_ind = s + 2 * min_n - (deriv ? 1 : 0);
28  assert(e_pow_ind + (deriv ? 1 : 0) >= 0);
29  double e_pow = (e_pow_ind < 0 ? 0.0 : std::pow(e, e_pow_ind)),
30  coef = (deriv ? s + 2 * min_n : 1);
31  for(
32  int gamma_ind2 = 0;
33  gamma_ind2 <= inner_index(-1, s, max_e_power);
34  ++gamma_ind2
35  ) {
36  result.second = (coef
37  *
38  __gamma_minus[gamma_ind1][gamma_ind2]
39  *
40  e_pow);
41  result.first += result.second;
42  e_pow *= e2;
43  if(deriv) coef += 2;
44  }
45  return result;
46  }
47 
48  std::pair<double, double> EccentricityExpansionCoefficients::p_0s(
49  double e,
50  int s,
51  unsigned max_e_power,
52  bool deriv
53  ) const
54  {
55  std::pair<double, double> result(0.0, 0.0);
56 
57  double e2 = std::pow(e, 2);
58  int min_n = std::max(0, -s),
59  alpha_ind1 = s + __max_e_power,
60  e_pow_ind = s + 2 * min_n - (deriv ? 1 : 0);
61  assert(e_pow_ind + (deriv ? 1 : 0) >= 0);
62  double e_pow = (e_pow_ind < 0 ? 0.0 : std::pow(e, e_pow_ind)),
63  coef = (deriv ? s + 2 * min_n : 1);
64  for(
65  int alpha_ind2 = 0;
66  alpha_ind2 <= inner_index(0, s, max_e_power);
67  ++alpha_ind2
68  ) {
69  result.second = coef * __alpha[alpha_ind1][alpha_ind2] * e_pow;
70  result.first += result.second;
71  e_pow *= e2;
72  if(deriv) coef += 2;
73  }
74  return result;
75  }
76 
77  std::pair<double, double> EccentricityExpansionCoefficients::p_p2s(
78  double e,
79  int s,
80  unsigned max_e_power,
81  bool deriv
82  ) const
83  {
84  std::pair<double, double> result(0.0, 0.0);
85 
86  double e2 = std::pow(e, 2);
87  int min_n = std::max(-1, -s + 1),
88  gamma_ind1 = s + __max_e_power - 2,
89  e_pow_ind = s + 2 * min_n - (deriv ? 1 : 0);
90  assert(e_pow_ind + (deriv ? 1 : 0) >= 0);
91  double e_pow = (e_pow_ind < 0 ? 0.0 : std::pow(e, e_pow_ind)),
92  coef = (deriv ? s + 2 * min_n : 1);
93  for(
94  int gamma_ind2 = 0;
95  gamma_ind2 <= inner_index(1, s, max_e_power);
96  ++gamma_ind2
97  ) {
98  result.second = coef * __gamma_plus[gamma_ind1][gamma_ind2] * e_pow;
99  result.first += result.second;
100  e_pow *= e2;
101  if(deriv) coef += 2;
102  }
103  return result;
104  }
105 
107  const std::string &tabulated_pms_fname,
108  int max_e_power
109  )
110  {
111  std::ifstream tabulated_coef(tabulated_pms_fname.c_str());
112  if(!tabulated_coef) throw Core::Error::IO(
113  "Unable to open eccentricity expansion file: "
114  +
115  tabulated_pms_fname
116  +
117  "!"
118  );
119  tabulated_coef >> __max_e_power;
120  if(max_e_power >= 0) {
121  if(__max_e_power<static_cast<unsigned>(max_e_power)) {
122  std::ostringstream msg;
123  msg << "Eccentricity expansion file '"
124  << tabulated_pms_fname
125  << "' stops at lower eccentricity power ("
126  << __max_e_power
127  <<") than requested ("
128  << max_e_power
129  << ") in EccentricityExpansionCoefficients::read()!";
130  throw Core::Error::BadFunctionArguments(msg.str());
131  }
132  __max_e_power = max_e_power;
133  }
134 
135  __alpha.resize(2 * __max_e_power + 1);
136  __gamma_plus.resize(2 * __max_e_power + 1);
137  __gamma_minus.resize(2 * __max_e_power + 1);
138 
139  for(
140  int epower = 0;
141  epower <= static_cast<int>(__max_e_power);
142  ++epower
143  ) {
144  for(int s = -epower - 2; s <= epower-2; s += 2) {
145  if(s) {
146  assert(s + static_cast<int>(__max_e_power) + 2 >= 0);
147  assert(s + __max_e_power + 2 < __gamma_minus.size());
148  std::vector<double>
149  &destination = __gamma_minus[s + __max_e_power + 2];
150  if(destination.size() == 0)
151  destination.resize(inner_index(-1, s, __max_e_power)
152  +
153  1);
154  assert(inner_index(-1, s, epower) >= 0);
155  assert(inner_index(-1, s, epower)
156  <static_cast<int>(destination.size()));
157  tabulated_coef >> destination[inner_index(-1,
158  s,
159  epower)];
160  }
161  }
162  for(int s = -epower; s <= epower; s += 2) {
163  assert(s + static_cast<int>(__max_e_power) >= 0);
164  assert(s + __max_e_power < __alpha.size());
165  std::vector<double> &destination=__alpha[s + __max_e_power];
166  if(destination.size() == 0)
167  destination.resize(inner_index(0, s, __max_e_power) + 1);
168  assert(inner_index(0, s, epower) >= 0);
169  assert(inner_index(0, s, epower)
170  <static_cast<int>(destination.size()));
171  tabulated_coef >> destination[inner_index(0, s, epower)];
172  }
173  for(int s = -epower + 2; s <= epower + 2; s += 2) {
174  if(s) {
175  assert(s + static_cast<int>(__max_e_power) - 2 >= 0);
176  assert(s + __max_e_power - 2 < __gamma_plus.size());
177  std::vector<double>
178  &destination=__gamma_plus[s + __max_e_power - 2];
179  if(destination.size() == 0)
180  destination.resize(inner_index(1, s, __max_e_power)
181  +
182  1);
183  assert(inner_index(1, s, epower) >= 0);
184  assert(inner_index(1, s, epower)
185  <static_cast<int>(destination.size()));
186  tabulated_coef >> destination[inner_index(1, s, epower)];
187  }
188  }
189  }
190  __useable = true;
191  }
192 
194  int m,
195  int s,
196  double e,
197  unsigned max_e_power,
198  bool deriv
199  ) const
200  {
201  if(!__useable)
202  throw Core::Error::Runtime(
203  "Attempting to evaluate Pms before reading in eccentricity "
204  "expansion coefficients!"
205  );
206 
207  std::pair<double, double> zero(0.0, 0.0);
208 
209  if(
210  s < -static_cast<int>(max_e_power) + m
211  ||
212  s > static_cast<int>(max_e_power) + m
213  )
214  return zero;
215 
216  switch(m) {
217  case -2 : return (s == 0 ? zero : p_m2s(e, s, max_e_power, deriv));
218  case 0 : return p_0s(e, s, max_e_power, deriv);
219  case 2 : return (s == 0 ? zero : p_p2s(e, s, max_e_power, deriv));
220  default : throw Core::Error::BadFunctionArguments(
221  "Asking for p_{m,s} with m other than +-2 and 0"
222  );
223  };
224  }
225 
226 } //End Evolve namespace.
Function arguments do not satisfy some requirement.
Definition: Error.h:73
std::vector< std::vector< double > > __gamma_minus
The expansion coefficients of ( in the [documentation]{InclinationEccentricity_pms1}).
int inner_index(int msign, int s, int epower) const
The inner index in the __alpha/gamma_plus/gamma_minus arrays.
Declares a class which provides the [ coefficients]{InclinationEccentricity_pms1}.
void read(const std::string &tabulated_pms_fname="", int max_e_power=-1)
Reads in tabulated expansion coefficients, making this object useable.
Any runtime error.
Definition: Error.h:61
Orientations of zones of bodies in a binary system.
std::pair< double, double > p_0s(double e, int s, unsigned max_e_power, bool deriv) const
Input/Output exception.
Definition: Error.h:118
std::vector< std::vector< double > > __gamma_plus
The expansion coefficients of ( in the [documentation]{InclinationEccentricity_pms1}).
unsigned __max_e_power
Maximum eccentricity power with all necessary coefficients known.
std::pair< double, double > operator()(int m, int s, double e, unsigned max_e_power, bool deriv) const
Taylor series approximation of and the contribution of the highest power eccentricity terms...
unsigned max_e_power() const
Maximum eccentricity power with all necessary coefficients known.
std::vector< std::vector< double > > __alpha
The expansion coefficients of ( along with the s factior in the [documentation]{InclinationEccentri...
std::pair< double, double > p_p2s(double e, int s, unsigned max_e_power, bool deriv) const
std::pair< double, double > p_m2s(double e, int s, unsigned max_e_power, bool deriv) const