Planetary Orbital Evolution due to Tides
Orbital evolution of two objects experiencing tides
testLockMonitoring.cpp
Go to the documentation of this file.
1 
8 #include "testLockMonitoring.h"
9 
10 namespace Evolve {
11 
12  const double epsilon = std::numeric_limits<double>::epsilon();
13 
14  void test_LockMonitoring::set_expansion_order(int max_orbital_multiplier)
15  {
16  Planet::Planet body1(1.0, 1.0), body2(1.0, 1.0);
17  BinarySystem system(body1, body2);
18  __zone.change_e_order(max_orbital_multiplier - 2, system, true, 0);
19  }
20 
22  double orbital_frequency,
23  double spin_frequency
24  )
25  {
26  __zone.configure(true,
27  0.0,
28  orbital_frequency,
29  0.0,
30  1.0,
31  spin_frequency,
32  0.0,
33  0.0,
34  true);
35  }
36 
38  const SpinOrbitLockInfo &lock_below,
39  const SpinOrbitLockInfo &lock_above,
40  std::ostringstream &message
41  )
42  {
43  message << lock_below.orbital_frequency_multiplier()
44  << "/"
45  << lock_below.spin_frequency_multiplier()
46  << " * Worb "
47  << " < W* < "
48  << lock_above.orbital_frequency_multiplier()
49  << "/"
50  << lock_above.spin_frequency_multiplier()
51  << " * Worb";
52  }
53 
55  std::ostringstream &message
56  )
57  {
58  if(__zone.lock_monitored(false).lock_direction() > 0) {
60  __zone.lock_monitored(true),
61  message);
62 
63  } else {
65  __zone.lock_monitored(false),
66  message);
67  }
68 
69  }
70 
72  double orbital_frequency,
73  double spin_frequency,
74  const SpinOrbitLockInfo &expected_lock_below,
75  const SpinOrbitLockInfo &expected_lock_above
76  )
77  {
78  set_orbital_spin_frequeqncy(orbital_frequency, spin_frequency);
79  std::ostringstream message;
80  message << "For Worb = " << orbital_frequency
81  << ", W* = " << spin_frequency
82  << ", should monitor ";
83  add_locks_to_message(expected_lock_below,
84  expected_lock_above,
85  message);
86 
87  message << ". auto selected terms to monitor: ";
89  message << ".";
90 
91  SpinOrbitLockInfo selected_lock_below, selected_lock_above;
92  if(__zone.lock_monitored(false).lock_direction() > 0) {
93  selected_lock_below = __zone.lock_monitored(false);
94  selected_lock_above = __zone.lock_monitored(true);
95  } else {
96  selected_lock_below = __zone.lock_monitored(true);
97  selected_lock_above = __zone.lock_monitored(false);
98  }
99 
100 
101  TEST_ASSERT_MSG(
102  expected_lock_below.term(
103  selected_lock_below.orbital_frequency_multiplier(),
104  selected_lock_below.spin_frequency_multiplier()
105  )
106  &&
107  (
108  expected_lock_below.lock_direction()
109  *
110  selected_lock_below.lock_direction()
111  >
112  0
113  ),
114  message.str().c_str()
115  );
116 
117  TEST_ASSERT_MSG(
118  expected_lock_above.term(
119  selected_lock_above.orbital_frequency_multiplier(),
120  selected_lock_above.spin_frequency_multiplier()
121  )
122  &&
123  (
124  expected_lock_above.lock_direction()
125  *
126  selected_lock_above.lock_direction()
127  >
128  0
129  ),
130  message.str().c_str()
131  );
132 
133  }
134 
135  double test_LockMonitoring::sample_range(std::pair<double, double> range,
136  unsigned position)
137  {
138  std::cerr.precision(19);
139  if(position == 0) {
140  if(range.first < 0) {
141  return range.first * (1.0 - epsilon);
142  } else if(range.first == 0)
143  return epsilon;
144  else
145  return range.first * (1.0 + epsilon);
146  } else if(position == 1)
147  return 0.5 * (range.first + range.second);
148  else {
149  if(range.second < 0)
150  return range.second * (1.0 + epsilon);
151  else if(range.second == 0)
152  return -epsilon;
153  else
154  return range.second * (1.0 - epsilon);
155  }
156  }
157 
158 
160  double lock_set_orbital_frequency,
161  double lock_set_spin_frequency,
162  double test_orbital_frequency,
163  std::pair<double, double> test_spin_frequency_range,
164  int orbital_frequency_multiplier,
165  int spin_frequency_multiplier,
166  int expected_correction
167  )
168  {
169  set_orbital_spin_frequeqncy(lock_set_orbital_frequency,
170  lock_set_spin_frequency);
171 
172  for(unsigned spin_choice = 0; spin_choice <= 2; ++spin_choice) {
173  double test_spin_frequency = sample_range(test_spin_frequency_range,
174  spin_choice);
175  __zone.configure(false,
176  0.0,
177  std::numeric_limits<double>::quiet_NaN(),
178  0.0,
179  1.0,
180  test_spin_frequency,
181  0.0,
182  0.0,
183  true);
184  double expected_tidal_frequency = (
185  expected_correction == 0
186  ? (
187  orbital_frequency_multiplier * test_orbital_frequency
188  -
189  spin_frequency_multiplier * test_spin_frequency
190  )
191  : expected_correction * epsilon
192  );
193  double calculated_tidal_frequency = __zone.forcing_frequency(
194  orbital_frequency_multiplier,
195  spin_frequency_multiplier,
196  test_orbital_frequency
197  );
198 
199  std::ostringstream message;
200  message.precision(19);
201  message << "With zone locks: ";
202  add_zone_locks_to_message(message);
203  message << ", Wtide(m=" << spin_frequency_multiplier
204  << ", s=" << orbital_frequency_multiplier
205  << ") for Worb = " << test_orbital_frequency
206  << ", W* = " << test_spin_frequency
207  << " is " << calculated_tidal_frequency
208  << " instead of " << expected_tidal_frequency;
209 
210  if(expected_correction == 0) {
211  double difference = (expected_tidal_frequency
212  -
213  calculated_tidal_frequency);
214  message << ", difference (expected - got): " << difference << ".";
215  TEST_ASSERT_MSG(
216  (
217  std::abs(difference) < 1e-14
218  &&
219  (
220  expected_tidal_frequency
221  *
222  calculated_tidal_frequency
223  >
224  0
225  ||
226  (
227  expected_tidal_frequency == 0
228  &&
229  calculated_tidal_frequency == 0
230  )
231  )
232  ),
233  message.str().c_str()
234  )
235  } else {
236  message << ".";
237  TEST_ASSERT_MSG(
238  calculated_tidal_frequency == expected_tidal_frequency,
239  message.str().c_str()
240  )
241  }
242  }
243  }
244 
246  int expansion_order,
247  int lower_lock_orbital_freuqency_multiplier,
248  double orbital_frequency
249  )
250  {
251  set_expansion_order(expansion_order);
252  double lock_set_spin_frequency = (
253  0.25
254  +
255  0.5 * lower_lock_orbital_freuqency_multiplier
256  ) * orbital_frequency;
257  for(
258  int spin_range_s = -3*expansion_order;
259  spin_range_s <= 3*expansion_order;
260  ++spin_range_s
261  ) {
262  for(int test_m = -2; test_m <= 2; test_m += 1) {
263  for(
264  int test_s = -expansion_order;
265  test_s <= expansion_order;
266  ++test_s
267  ) {
268  std::pair<double, double> spin_frequency_range(
269  (0.5 * spin_range_s) * orbital_frequency,
270  0.5 * (spin_range_s + 1) * orbital_frequency
271  );
272  int expected_correction = 0;
273  if(test_m != 0) {
274  int scaled_test_s = 2 * test_s / test_m;
275  if(
276  (
277  scaled_test_s
278  >
279  lower_lock_orbital_freuqency_multiplier
280  )
281  &&
282  (
283  scaled_test_s <= spin_range_s
284  )
285  )
286  expected_correction = boost::math::sign(test_m);
287 
288  if(
289  (
290  scaled_test_s
291  <=
292  lower_lock_orbital_freuqency_multiplier
293  )
294  &&
295  (
296  scaled_test_s
297  >
298  spin_range_s
299  )
300  )
301  expected_correction = -boost::math::sign(test_m);
302  }
303 
305  orbital_frequency,
306  lock_set_spin_frequency,
307  orbital_frequency,
308  spin_frequency_range,
309  test_s,
310  test_m,
311  expected_correction
312  );
313  }
314  }
315  }
316  }
317 
318 
320  : __zone(1.0, 1.0, 1.0)
321  {
322  __zone.setup(
323  std::vector<double>(),
324  std::vector<double>(),
325  std::vector<double>(1, 0.0),
326  std::vector<double>(1, 0.0),
327  1.0,
328  1.0,
329  1.0
330  );
331 
334  }
335 
337  {
340  0.10,
341  SpinOrbitLockInfo(0, 1, 1),
342  SpinOrbitLockInfo(1, 2, -1));
343 
345  0.30,
346  SpinOrbitLockInfo(1, 2, 1),
347  SpinOrbitLockInfo(1, 1, -1));
348 
350  0.57,
351  SpinOrbitLockInfo(1, 1, 1),
352  SpinOrbitLockInfo(3, 2, -1));
353 
354 
356  0.67,
357  SpinOrbitLockInfo(2, 1, 1),
358  SpinOrbitLockInfo(3, 1, -1));
359 
361  0.69,
362  SpinOrbitLockInfo(3, 1, 1),
363  SpinOrbitLockInfo(1, 0, -1));
364 
366  -0.12,
367  SpinOrbitLockInfo(-1, 2, 1),
368  SpinOrbitLockInfo(0, 1, -1));
369 
371  -0.32,
372  SpinOrbitLockInfo(-1, 1, 1),
373  SpinOrbitLockInfo(-1, 2, -1));
374 
376  -0.45,
377  SpinOrbitLockInfo(-3, 2, 1),
378  SpinOrbitLockInfo(-1, 1, -1));
379 
381  -0.61,
382  SpinOrbitLockInfo(-3, 1, 1),
383  SpinOrbitLockInfo(-2, 1, -1));
384 
386  -0.67,
387  SpinOrbitLockInfo(-1, 0, 1),
388  SpinOrbitLockInfo(-3, 1, -1));
389  }
390 
392  {
393  const int expansion_order = 10;
394  for(
395  int orbital_frequency_multiplier = -3 * expansion_order;
396  orbital_frequency_multiplier <= 3 * expansion_order;
397  ++orbital_frequency_multiplier
398  )
399  check_unlocked_tidal_frequency(expansion_order,
400  orbital_frequency_multiplier,
401  0.32);
402  }
403 
404 } //End Evolve namespace.
void test_tidal_frequency_fix()
Test fix applied to the tidal frequency of tidal term(s) matching lower boundary lock.
void check_monitored_locks(double orbital_frequency, double spin_frequency, const SpinOrbitLockInfo &expected_lock_below, const SpinOrbitLockInfo &expected_lock_above)
Verify a single expectation of what locks would be monitored in a given situation.
const SpinOrbitLockInfo & lock_monitored(bool other=false) const
Useful for debugging.
int orbital_frequency_multiplier() const
The multiplier in front of the orbital frequency in the lock.
virtual void change_e_order(unsigned new_e_order, BinarySystem &system, bool primary, unsigned zone_index)
Changes the order of the eccentricity expansion performed.
Single zone non-evolving planets with huge dissipation, so they always remain locked to the disk...
Definition: Planet.h:21
Orientations of zones of bodies in a binary system.
void set_orbital_spin_frequeqncy(double orbital_frequency, double spin_frequency)
Change the orbital and spin frequencies for __zone.
void check_tidal_frequency_range(double lock_set_orbital_frequency, double lock_set_spin_frequency, double test_orbital_frequency, std::pair< double, double > test_spin_frequency_range, int orbital_frequency_multiplier, int spin_frequency_multiplier, int expected_correction)
Verify a single expectation for fixing of a tidal term in a given situation over a range of spin freq...
test_LockMonitoring()
Create the test suite.
int spin_frequency_multiplier() const
The multiplier in front of the spin frequency in the lock.
Planet::PlanetZone __zone
A dissipative zone to run the tests on.
void add_zone_locks_to_message(std::ostringstream &message)
void check_unlocked_tidal_frequency(int expansion_order, int lower_lock_orbital_freuqency_multiplier, double orbital_frequency)
Check that lock-corrected tidal frequency reproduces expectations for a single set of monitored locks...
void configure(bool initialize, double age, double orbital_frequency, double eccentricity, double orbital_angmom, double spin, double inclination, double periapsis, bool spin_is_frequency)
Calls the usual DissipatingZone::configure but with zero inclination and periapsis.
Definition: PlanetZone.h:95
double sample_range(std::pair< double, double > range, unsigned position)
Pick a just inside each boundary or in the middle of a range.
bool term(int orbital_freq_mult, int spin_freq_mult) const
void set_expansion_order(int max_orbital_multiplier)
Change the order of the tidal potential expansion used by __zone.
Unit tests that check the machinery for monitoring potential tidal locks.
double forcing_frequency(int orbital_frequency_multiplier, int spin_frequency_multiplier, double orbital_frequency) const
The tidal forcing frequency for the given term and orbital frequency.
void test_lock_init()
Test whether the correct tidal terms are selected for lock monitoring when and.
void add_locks_to_message(const SpinOrbitLockInfo &lock_below, const SpinOrbitLockInfo &lock_above, std::ostringstream &message)
Add information about the given locks relative to the tidal frequency to the test message...
Describes a system of two bodies orbiting each other.
Definition: BinarySystem.h:56
Defines a lock between the spin of a dissipating body and the orbit.
void setup(const std::vector< double > &tidal_frequency_breaks, const std::vector< double > &spin_frequency_breaks, const std::vector< double > &tidal_frequency_powers, const std::vector< double > &spin_frequency_powers, double reference_phase_lag, double inertial_mode_enhancement=1.0, double inertial_mode_sharpness=10.0)
Seup the zone with the given breaks/powers and inertial mode enhancement. Continuous accress all brea...