Planetary Orbital Evolution due to Tides
Orbital evolution of two objects experiencing tides
LagSpinBreakCondition.cpp
1 #define BUILDING_LIBRARY
4 
5 namespace Evolve {
6 
7  void LagSpinBreakCondition::set_num_subconditions()
8  {
9 
10  if(
11  __powerlaw_index == 0
12  ||
13  __powerlaw_index == __zone.__spin_frequency_breaks.size()
14  )
15  __num_subconditions = 1;
16  else
17  __num_subconditions = 2;
18  }
19 
20  double LagSpinBreakCondition::derivative(double surf_angmom_deriv,
21  double wcritical) const
22  {
23  return (
24  (
25  (__zone.spin_frequency() < 0 ? -1.0 : 1.0)
26  *
27  surf_angmom_deriv
28  -
29  __zone.moment_of_inertia(1)
30  *
31  __zone.spin_frequency()
32  )
33  /
34  (__zone.moment_of_inertia() * wcritical)
35  );
36  }
37 
38  void LagSpinBreakCondition::fill_locked_derivs(
40 #ifndef NDEBUG
41  evol_mode
42 #endif
43  ,
44  const std::valarray<double> &orbit,
45  const std::valarray<double> &derivatives,
46  std::valarray<double> &stop_deriv
47  ) const
48  {
49  assert(evol_mode == Core::BINARY);
50  double deriv_factor = (-1.5 * __zone.spin_frequency()
51  *
52  derivatives[0] / orbit[0]);
53  unsigned subcond = 0;
54  if(__powerlaw_index > 0)
55  stop_deriv[subcond++] = (
56  deriv_factor
57  /
58  __zone.__spin_frequency_breaks[__powerlaw_index - 1]
59  );
60  if(__powerlaw_index < __zone.__spin_frequency_breaks.size())
61  stop_deriv[subcond] = (
62  deriv_factor
63  /
64  __zone.__spin_frequency_breaks[__powerlaw_index]
65  );
66  }
67 
68  void LagSpinBreakCondition::fill_unlocked_derivs(
69  Core::EvolModeType evol_mode,
70  const std::valarray<double> &,
71  const std::valarray<double> &derivatives,
72  std::valarray<double> &stop_deriv
73  ) const
74  {
75  unsigned angmom_index = 1 + __zone_index + 2 * __body.number_zones();
76  if(evol_mode == Core::BINARY)
77  angmom_index += (
78  2 * __other_body.number_zones()
79  +
80  (__primary
81  ? 0
82  : (__other_body.number_zones()
83  -
84  __other_body.number_locked_zones()))
85  );
86  else angmom_index -= 3;
87  assert(angmom_index <= derivatives.size());
88 
89  double surf_angmom_deriv = derivatives[angmom_index];
90 
91  if(__powerlaw_index > 0)
92  stop_deriv[0] = derivative(
93  surf_angmom_deriv,
94  __zone.__spin_frequency_breaks[__powerlaw_index - 1]
95  );
96  if(__powerlaw_index < __zone.__spin_frequency_breaks.size())
97  stop_deriv[1] = derivative(
98  surf_angmom_deriv,
99  __zone.__spin_frequency_breaks[__powerlaw_index]
100  );
101  }
102 
103  LagSpinBreakCondition::LagSpinBreakCondition(
105  const DissipatingBody &body,
106  const DissipatingBody &other_body,
107  bool primary,
108  unsigned zone_index
109  ) :
110  __zone(zone),
111  __body(body),
112  __other_body(other_body),
113  __primary(primary),
114  __zone_index(zone_index),
115  __powerlaw_index(__zone.__spin_index)
116  {
118  }
119 
120  std::valarray<double> LagSpinBreakCondition::operator()(
121  Core::EvolModeType evol_mode,
122  const std::valarray<double> &orbit,
123  const std::valarray<double> &derivatives,
124  std::valarray<double> &stop_deriv
125  ) const
126  {
127  assert(evol_mode != Core::LOCKED_SURFACE_SPIN);
128  assert(__primary || evol_mode == Core::BINARY);
129 
130  stop_deriv.resize(__num_subconditions, Core::NaN);
131 
132 
133  if(__zone.locked())
134  fill_locked_derivs(evol_mode, orbit, derivatives, stop_deriv);
135  else
136  fill_unlocked_derivs(evol_mode, orbit, derivatives, stop_deriv);
137 
138  std::valarray<double> result(__num_subconditions);
139 
140  unsigned subcond = 0;
141  if(__powerlaw_index > 0) {
142  double critical_frequency =
144  result[subcond++] = (
145  (__zone.spin_frequency() - critical_frequency)
146  /
147  critical_frequency
148  );
150  double critical_frequency =
152  result[subcond] = (
153  (__zone.spin_frequency() - critical_frequency)
154  /
155  critical_frequency
156  );
157  }
158  return result;
159  }
160 
161  void LagSpinBreakCondition::reached(
162  short
163 #ifndef NDEBUG
164  deriv_sign
165 #endif
166  ,
167  unsigned index)
168  {
169  assert(index < __num_subconditions);
170 
171  if(__powerlaw_index > 0 && index == 0) {
172  assert(deriv_sign == -1);
175  } else {
176  assert(deriv_sign == 1);
180  }
181 
183 
184  }
185 
186  short LagSpinBreakCondition::expected_crossing_deriv_sign(
187  unsigned index
188  ) const
189  {
190  if(index == 1 || __powerlaw_index == 0) {
191  assert(__powerlaw_index
192  <
194  return 1;
195  } else {
196  return -1;
197  }
198  }
199 
200  std::string LagSpinBreakCondition::describe(int index) const
201  {
202  std::ostringstream description;
203  description << (__primary ? "Primary" : "Secondary")
204  << " body, zone "
205  << __zone_index
206  << " spin frequency leaving the interval ";
207  if(__powerlaw_index > 0 && index <= 0)
208  description
210  << " < ";
211  description << " |Wspin| ";
212  if(
214  &&
215  (
216  index < 0
217  ||
218  index == static_cast<int>(__num_subconditions) - 1
219  )
220  )
221  description << " < "
223  description << std::endl;
224  return description.str();
225  }
226 
227 }//End Evolve namespace
std::vector< double >::size_type __spin_index
The index within __spin_frequency_powers of the powerlaw now in effect.
struct LIB_PUBLIC BrokenPowerlawPhaseLagZone
Opaque struct to cant to/from Evolve::BrokenPowerlawPhasLagZone.
Definition: CInterface.h:41
Orientations of zones of bodies in a binary system.
Declares a stopping condition monitoring for critical spin frequencies.
virtual bool locked(int orbital_frequency_multiplier, int spin_frequency_multiplier) const
Should return true iff the given term is presently locked.
std::vector< double > __spin_frequency_breaks
The locations of the breaks in spin frequency in rad/day.
EvolModeType
The various evolution modes.
Definition: Common.h:42
Declares the class that provides the phase lag function to DissipatingZone objects.
BrokenPowerlawPhaseLagZone & __zone
The zone being monitored (for more convenient access).
void set_num_subconditions()
Set the appropriate value of __num_subcondition.
std::vector< double >::size_type __powerlaw_index
The index of the currently active powerlaw within __zone.__tidal_frequency_powers.
double spin_frequency() const
The spin frequency of the given zone.