Planetary Orbital Evolution due to Tides
Orbital evolution of two objects experiencing tides
testGravitationalPotential.cpp
Go to the documentation of this file.
1 
9 
10 namespace Evolve {
11 
13  const EccentricOrbit &orbit
14  ) const
15  {
16  std::cout << std::setw(25) << "phase"
17  << std::setw(25) << "x"
18  << std::setw(25) << "y"
19  << std::setw(25) << "z"
20  << std::endl;
21  for(double phase = 0.0; phase < 4.0 * M_PI; phase += 0.001 * M_PI) {
22  Eigen::Matrix<long double, 3, 1> secondary_position =
23  orbit.secondary_position(phase);
24  std::cout << std::setw(25) << phase
25  << std::setw(25) << secondary_position[0]
26  << std::setw(25) << secondary_position[1]
27  << std::setw(25) << secondary_position[2]
28  << std::endl;
29  }
30  }
31 
33  double primary_mass,
34  double secondary_mass,
35  double semimajor,
36  double eccentricity,
37  double inclination,
38  double arg_of_periapsis,
39  const Eigen::Matrix<long double, 3, 1> &position,
40  unsigned expansion_order
41  ) const
42  {
43  TidalPotential exact_potential(primary_mass,
44  secondary_mass,
45  semimajor,
46  eccentricity,
47  inclination,
48  arg_of_periapsis);
49  TidalPotentialExpansion approx_potential(primary_mass,
50  secondary_mass,
51  semimajor,
52  eccentricity,
53  inclination,
54  arg_of_periapsis);
55 
56  double orbital_period = exact_potential.orbit().orbital_period();
57  std::ostringstream Uexact_label, Uapprox_label;
58  Uexact_label << "Uexact("
59  << "x=" << position[0]
60  << ", y=" << position[1]
61  << ", z=" << position[2]
62  << ", t=time)";
63  Uapprox_label << "Uapprox("
64  << "x=" << position[0]
65  << ", y=" << position[1]
66  << ", z=" << position[2]
67  << ", t=time)";
68  std::cout << std::setw(35) << "time/Porb"
69  << std::setw(35) << Uexact_label.str()
70  << std::setw(35) << Uapprox_label.str()
71  << std::endl;
72  for(
73  double time = 0;
74  time < 5.0 * orbital_period;
75  time += 0.01 * orbital_period
76  ) {
77  std::cout << std::setw(35) << time/orbital_period
78  << std::setw(35) << exact_potential(position, time)
79  << std::setw(35) << approx_potential(position,
80  time,
81  expansion_order)
82  << std::endl;
83  }
84  }
85 
86 
88  const Eigen::Matrix<long double, 3, 1> &position,
89  const EccentricOrbit &orbit,
90  double expansion_precision
91  ) const
92  {
93  const double safety = 3.0;
94 
95  double scaled_distance = (
96  position.norm()
97  /
98  (orbit.semimajor() * (1.0 - orbit.eccentricity()))
99  );
100 
101  return (
102  (
104  *
106  /
107  (
109  *
110  (1.0 - orbit.eccentricity())
111  )
112  )
113  *
114  std::pow(scaled_distance, 2)
115  *
116  (safety * scaled_distance + expansion_precision)
117  );
118  }
119 
121  TidalPotentialExpansion &approx_potential,
122  const TidalPotential &exact_potential,
123  const Eigen::Matrix<long double, 3, 1> &position
124  )
125  {
126  double orbital_period = exact_potential.orbit().orbital_period(),
127  abs_tolerance = abs_precision(
128  position,
129  exact_potential.orbit(),
130  approx_potential.get_expansion_precision()
131  ),
132  eccentricity = exact_potential.orbit().eccentricity();
133 
134  unsigned expansion_order =
136 
137  std::ostringstream message_start;
138  message_start.setf(std::ios_base::scientific);
139  message_start.precision(16);
140  message_start << "M = " << exact_potential.orbit().primary_mass()
141  << "; M' = " << exact_potential.orbit().secondary_mass()
142  << "; a = " << exact_potential.orbit().semimajor()
143  << "; e = " << eccentricity
144  << "; inclination = " << exact_potential.inclination()
145  << "; periapsis = " << exact_potential.arg_of_periapsis()
146  << "; U(x = " << position[0]
147  << ", y = " << position[1]
148  << ", z = " << position[2];
149 
150  for(
151  double time = 0;
152  time < 5.0 * orbital_period;
153  time += 0.03 * M_PI * orbital_period
154  ) {
155  double expected = exact_potential(position, time);
156  double got = approx_potential(position, time, expansion_order);
157 
158  std::ostringstream message;
159  message.precision(16);
160  message.setf(std::ios_base::scientific);
161  message << message_start.str()
162  << ", t = " << time
163  << " = " << time / orbital_period
164  << " Porb): expected " << expected
165  << "; got " << got
166  << "; difference " << got - expected
167  << " > " << abs_tolerance;
168 
169 #ifdef VERBOSE_DEBUG
170  std::cerr << message.str() << std::endl;
171 #endif
172 
173  TEST_ASSERT_MSG(
174  check_diff(got,
175  expected,
176  0.0,
177  abs_tolerance),
178  message.str().c_str()
179  );
180  }
181  }
182 
184  double primary_mass,
185  double secondary_mass,
186  double semimajor,
187  double eccentricity,
188  double inclination,
189  double arg_of_periapsis
190  )
191  {
192  TidalPotential exact_potential(primary_mass,
193  secondary_mass,
194  semimajor,
195  eccentricity,
196  inclination,
197  arg_of_periapsis);
198  TidalPotentialExpansion approx_potential(primary_mass,
199  secondary_mass,
200  semimajor,
201  eccentricity,
202  inclination,
203  arg_of_periapsis);
204 
205  long double test_offsets[]= {-0.01,
206  -0.001,
207  -1e-6,
208  0.0,
209  1e-6,
210  0.001,
211  0.01};
212  unsigned num_offsets = sizeof(test_offsets) / sizeof(long double);
213  typedef long double ldbl;
214  for(unsigned z_index = 0; z_index < num_offsets; ++z_index)
215  for(unsigned y_index = 0; y_index < num_offsets; ++y_index)
216  for(unsigned x_index = 0; x_index < num_offsets; ++x_index) {
218  approx_potential,
219  exact_potential,
220  Eigen::Matrix<ldbl, 3, 1> (test_offsets[x_index],
221  test_offsets[y_index],
222  test_offsets[z_index])
223  );
224  }
225  }
226 
228  {
229  double test_angles[] = {-M_PI/2, -1.0, -0.1, 0.0, 0.1, 1.0, M_PI/2};
230  unsigned num_angles = sizeof(test_angles) / sizeof(double);
231  for(
232  double e = 0.9;
233  e <= 0.95;
234  e += 0.1
235  ) {
236  std::cout << "Eccentricity : " << e << std::endl;
237 
238  for(
239  unsigned inclination_i = 0;
240  inclination_i < num_angles;
241  ++inclination_i
242  ) {
243  for(
244  unsigned periapsis_i = 0;
245  periapsis_i < num_angles;
246  ++periapsis_i
247  ) {
248  test_system(1.0,
249  0.1,
250  M_PI,
251  e,
252  test_angles[inclination_i],
253  2.0 * test_angles[periapsis_i]);
254  }
255  }
256  }
257  }
258 
260  {
262  }
263 
264 } //End Evolve namespace.
double get_expansion_precision() const
Return the expansion precision target for the expansion terms.
Basic description of two bodies in an eccentric orbit.
Unit tests that check the expansion of the gravitational potential vs. analytic expressions.
double inclination() const
See __inclination attribute.
void test_expansion()
Test the expansion of the potential for multiple system configurations, locations and times...
void print_tidal_potential(double primary_mass, double secondary_mass, double semimajor, double eccentricity, double inclination, double arg_of_periapsis, const Eigen::Matrix< long double, 3, 1 > &position, unsigned expansion_order) const
Print to stdout the value of the tidal potential without an approximation and using the expansion as ...
void test_system(double primary_mass, double secondary_mass, double semimajor, double eccentricity, double inclination, double arg_of_periapsis)
Test the expansion for a given system, sampling positions and times.
Evaluate the tidal potential using the expansion.
double arg_of_periapsis() const
The argument of periapsis of the system.
double eccentricity() const
The semimajor axis of the system.
double semimajor() const
The semimajor axis of the system.
Orientations of zones of bodies in a binary system.
const double solar_radius
Radius of the sun [m].
void test_single_point(TidalPotentialExpansion &approx_potential, const TidalPotential &exact_potential, const Eigen::Matrix< long double, 3, 1 > &position)
Test the expansion for a given system at a given position, sampling time.
double abs_precision(const Eigen::Matrix< long double, 3, 1 > &position, const EccentricOrbit &orbit, double expansion_precision) const
double primary_mass() const
The semimajor axis of the system.
bool check_diff(double x, double y, double frac_tolerance, double abs_tolerance)
Returns true iff .
Definition: Common.cpp:3
const double solar_mass
Mass of the sun [kg].
static unsigned required_expansion_order(double e)
The maximum orbital frequency multiplier to include in the potential Fourier expansion in order to ac...
Calculate the tidal potential over one component of an eccentric binary.
const EccentricOrbit & orbit() const
An unmutable reference to the binary orbit.
void print_orbit(const EccentricOrbit &orbit) const
Print to stdout the location of the secondary relative to the primary as a function of time for the g...
Eigen::Matrix< long double, 3, 1 > secondary_position(double orbital_phase) const
Secondary position vector in a coordinate system centered on the primary, with and ...
double orbital_period() const
The orbital period of the system in days.
double secondary_mass() const
The semimajor axis of the system.
const double G
Gravitational constant in SI.