Planetary Orbital Evolution due to Tides
Orbital evolution of two objects experiencing tides
DissipatingZone.h
Go to the documentation of this file.
1 
9 #ifndef __DISSIPATING_ZONE_H
10 #define __DISSIPATING_ZONE_H
11 
12 #include "ZoneOrientation.h"
13 #include "../Core/SharedLibraryExportMacros.h"
14 #include "../Core/Error.h"
15 #include "TidalPotentialTerms.h"
16 #include "DissipationQuantities.h"
17 #include "SpinOrbitLockInfo.h"
19 #include "BreakLockCondition.h"
20 #include "SynchronizedCondition.h"
21 #include "../Core/Common.h"
22 #include <valarray>
23 #include <boost/math/special_functions/sign.hpp>
24 
25 namespace Evolve {
26 
31 
34 
37 
40 
43 
46 
49 
52 
55 
58 
61 
64 
67 
70 
73 
76 
79 
85 
88  }; //End ZoneEvolutionQuantities enumeration.
89 
91  std::ostream &operator<<(std::ostream &os,
92  const ZoneEvolutionQuantities &evol_var);
93 
95  class BinarySystem;
96 
100  public:
101  double
104 
106  m,
107 
109  m_plus_one;
110 
111  TidalTermTriplet(double m_minus_one_value = 0.0,
112  double m_value = 0.0,
113  double m_plus_one_value = 0.0):
114  m_minus_one(m_minus_one_value),
115  m(m_value),
116  m_plus_one(m_plus_one_value)
117  {}
118 
119  TidalTermTriplet &operator=(const TidalTermTriplet &rhs)
120  {
121  m_minus_one = rhs.m_minus_one;
122  m = rhs.m;
123  m_plus_one = rhs.m_plus_one;
124  return *this;
125  }
126  };
127 
128 
129 
132  class LIB_PUBLIC DissipatingZone : public ZoneOrientation {
133  private:
136 
139 
142  static const double __torque_x_plus_coef[];
143 
146  static const double __torque_x_minus_coef[];
147 
148  double
150  __angular_momentum,
151 
153  __angular_momentum_evolution_rate,
154 
157 
159  __orbital_frequency,
160 
162  __orbital_angmom;
163 
164 
173  std::valarray<double> __power,
174 
179  __torque_x,
180 
185  __torque_y,
186 
191  __torque_z;
192 
198 
201  __other_lock;
202 
204  std::vector< std::list<double> > __evolution_real;
205 
207  std::vector< std::list<int> > __evolution_integer;
208 
212 
215 
222  void fix_forcing_frequency(
224  const SpinOrbitLockInfo &limit,
225 
228  int orbital_frequency_multiplier,
229 
232  int spin_frequency_multiplier,
233 
236  double &forcing_frequency
237  ) const;
238 
243  void update_lock_to_lower_expansion_order(SpinOrbitLockInfo &lock);
244 
247  void limit_above_lock_per_expansion_order(
248  int proposed_orbital_multiplier,
249  int proposed_spin_multiplier
250  );
251 
254  void set_faster_spin_lock(
260  int proposed_orbital_multiplier,
261 
267  int proposed_spin_multiplier
268  );
269 
274  void select_locks_to_monitor();
275 
277  void add_tidal_term(
279  int m,
280 
282  int mp,
283 
285  double tidal_frequency,
286 
290  const TidalTermTriplet &U_value,
291 
293  const TidalTermTriplet &U_i_deriv,
294 
296  const TidalTermTriplet &U_e_deriv
297  );
298 
301  virtual void check_locks_consistency() const;
302 
303  protected:
305  void initializing(bool flag) {__initializing = flag;}
306 
308  void configure_spin(
310  double spin,
311 
313  bool spin_is_frequency
314  );
315 
316  public:
317  DissipatingZone();
318 
321  virtual void configure(
323  bool initialize,
324 
326  double age,
327 
329  double orbital_frequency,
330 
332  double eccentricity,
333 
335  double orbital_angmom,
336 
339  double spin,
340 
342  double inclination,
343 
346  double periapsis,
347 
350  bool spin_is_frequency
351  );
352 
357  double angular_momentum,
358 
360  double inclination,
361 
363  double periapsis
364  )
365  {
366  __angular_momentum_evolution_rate = angular_momentum;
367  ZoneOrientation::set_evolution_rates(inclination, periapsis);
368  }
369 
375  double forcing_frequency(
378  int orbital_frequency_multiplier,
379 
382  int spin_frequency_multiplier,
383 
385  double orbital_frequency
386  ) const;
387 
390  void set_reference_zone_angmom(double reference_angmom)
391  {__orbital_angmom=reference_angmom;}
392 
398  double periapsis_evolution(
401  const Eigen::Vector3d &orbit_torque,
402 
406  const Eigen::Vector3d &zone_torque,
407 
415  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV,
416 
420  const Eigen::Vector3d &orbit_torque_deriv=
421  Eigen::Vector3d(),
422 
426  const Eigen::Vector3d &zone_torque_deriv=Eigen::Vector3d()
427  );
428 
434  double inclination_evolution(
437  const Eigen::Vector3d &orbit_torque,
438 
442  const Eigen::Vector3d &zone_torque,
443 
455  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV,
456 
460  const Eigen::Vector3d &orbit_torque_deriv=Eigen::Vector3d(),
461 
465  const Eigen::Vector3d &zone_torque_deriv=Eigen::Vector3d()
466  );
467 
468 
470  virtual bool locked(int orbital_frequency_multiplier,
471  int spin_frequency_multiplier) const
472  {return __lock(orbital_frequency_multiplier,
473  spin_frequency_multiplier);}
474 
476  virtual bool locked() const
477  {return __lock;}
478 
480  const SpinOrbitLockInfo &lock_held() const {return __lock;}
481 
484  void release_lock();
485 
487  void release_lock(
489  short direction
490  );
491 
493  void set_lock(int orbital_frequency_multiplier,
494  int spin_frequency_multiplier)
495  {
496  assert(!__lock);
497  __lock.set_lock(orbital_frequency_multiplier,
498  spin_frequency_multiplier);
499  }
500 
509  virtual double modified_phase_lag(
512  int orbital_frequency_multiplier,
513 
516  int spin_frequency_multiplier,
517 
519  double forcing_frequency,
520 
525  Dissipation::QuantityEntry entry,
526 
530  double &above_lock_value
531  ) const =0;
532 
535  virtual double love_coefficient(
538  int orbital_frequency_multiplier,
539 
542  int spin_frequency_multiplier,
543 
548  Dissipation::QuantityEntry entry
549  ) const =0;
550 
553  virtual double moment_of_inertia(
559  int deriv_order=0
560  ) const =0;
561 
564  virtual double moment_of_inertia(
566  double age,
567 
573  int deriv_order=0
574  ) const =0;
575 
577  double spin_frequency() const {return __spin_frequency;}
578 
580  double angular_momentum() const {return __angular_momentum;}
581 
583  double tidal_power(
588  bool above,
589 
591  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
592  ) const
593  {
594  assert(entry < Dissipation::END_DIMENSIONLESS_DERIV);
595  assert(2 * entry + 1 < static_cast<int>(__power.size()));
596 
597  return __power[2 * entry + (above? 1 : 0)];
598  }
599 
602  double tidal_power(
605  double above_fraction,
606 
608  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
609  ) const
610  {
611 
612  assert(!locked() || (above_fraction >= 0 && above_fraction <= 1));
613  assert(entry < Dissipation::END_DIMENSIONLESS_DERIV);
614  assert(2 * entry + 1 < static_cast<int>(__power.size()));
615 
616  return (
617  above_fraction * __power[2 * entry + 1]
618  +
619  (1.0 - above_fraction) * __power[2 * entry]
620  );
621  }
622 
627  bool above,
628  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
629  ) const
630  {
631  assert(entry < Dissipation::END_DIMENSIONLESS_DERIV);
632  assert(2 * entry + 1 < static_cast<int>(__torque_x.size()));
633 
634  return __torque_x[2 * entry + (above ? 1 : 0)];
635  }
636 
642  double above_fraction,
643 
646  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
647  ) const
648  {
649  assert(
650  !locked() || (above_fraction >= 0 && above_fraction <= 1)
651  );
652  assert(entry < Dissipation::END_DIMENSIONLESS_DERIV);
653  assert(
654  2 * entry + 1
655  <
656  static_cast<int>(__torque_x.size())
657  );
658 
659  return (above_fraction * __torque_x[2 * entry + 1]
660  +
661  (1.0 - above_fraction) * __torque_x[2 * entry]);
662  }
663 
668  bool above,
669  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
670  ) const
671  {
672  assert(entry < Dissipation::END_DIMENSIONLESS_DERIV);
673  assert(
674  2 * entry + 1
675  <
676  static_cast<int>(__torque_y.size())
677  );
678 
679  return __torque_y[2 * entry + (above? 1 : 0)];
680  }
681 
687  double above_fraction,
688 
691  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
692  ) const
693  {
694  assert(!locked() || (above_fraction >= 0 && above_fraction <= 1));
695  assert(entry < Dissipation::END_DIMENSIONLESS_DERIV);
696  assert(2 * entry + 1 < static_cast<int>(__torque_y.size()));
697 
698  return (above_fraction * __torque_y[2 * entry + 1]
699  +
700  (1.0 - above_fraction) * __torque_y[2 * entry]);
701  }
702 
707  bool above,
708  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
709  ) const
710  {
711  assert(entry < Dissipation::END_DIMENSIONLESS_DERIV);
712  assert(2 * entry + 1 < static_cast<int>(__torque_z.size()));
713 
714  return __torque_z[2 * entry + (above? 1 : 0)];
715  }
716 
722  double above_fraction,
723 
726  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
727  ) const
728  {
729  assert(!locked() || (above_fraction >= 0 && above_fraction <= 1));
730  assert(entry < Dissipation::END_DIMENSIONLESS_DERIV);
731  assert(2 * entry + 1 < static_cast<int>(__torque_z.size()));
732 
733  return (above_fraction * __torque_z[2 * entry + 1]
734  +
735  (1.0 - above_fraction) * __torque_z[2 * entry]);
736  }
737 
739  //configure()).
743  virtual double outer_radius(
748  int deriv_order = 0
749  ) const =0;
750 
753  virtual double outer_radius(double age, int deriv_order=0) const =0;
754 
760  virtual double outer_mass(
765  int deriv_order=0
766  ) const =0;
767 
770  virtual double outer_mass(double age, int deriv_order=0) const =0;
771 
774  virtual unsigned expansion_order() const {return __expansion_order;}
775 
777  virtual void change_expansion_order(
779  unsigned new_expansion_order,
780 
782  BinarySystem &system,
783 
785  bool primary,
786 
788  unsigned zone_index
789  );
790 
792  virtual void add_to_evolution();
793 
795  virtual void rewind_evolution(
797  unsigned nsteps
798  );
799 
801  virtual void reset_evolution();
802 
804  const std::list<double> &get_evolution_real(
805  ZoneEvolutionQuantities quantity
806  ) const
807  {
808  assert(quantity < NUM_REAL_EVOL_QUANTITIES);
809 
810  return __evolution_real[quantity];
811  }
812 
814  const std::list<int> &get_evolution_integer(
815  ZoneEvolutionQuantities quantity
816  ) const
817  {
818  assert(quantity >= NUM_REAL_EVOL_QUANTITIES);
819 
820  return __evolution_integer[quantity - NUM_REAL_EVOL_QUANTITIES];
821  }
822 
823 
826  unsigned locked_zone_index() const
827  {
828  assert(__lock);
829 
830  return __locked_zone_index;
831  }
832 
834  unsigned &locked_zone_index()
835  {
836  assert(__lock);
837 
838  return __locked_zone_index;
839  }
840 
842  virtual bool dissipative() const =0;
843 
846  virtual bool can_lock() const =0;
847 
852  virtual CombinedStoppingCondition *stopping_conditions(
854  BinarySystem &system,
855 
857  bool primary,
858 
860  unsigned zone_index
861  );
862 
864  virtual void spin_jumped()
865  {select_locks_to_monitor();}
866 
870  virtual void reached_critical_age(double)
871  {assert(false);}
872 
875  virtual double next_stop_age() const
876  {return Core::Inf;}
877 
879  const SpinOrbitLockInfo &lock_monitored(bool other=false) const
880  {
881  if(other)
882  return __other_lock;
883  else
884  return __lock;
885  }
886 
892  {
893  std::swap(__lock, __other_lock);
894  }
895  }; //End DissipatingZone class.
896 
897 } //End Evolve namespace.
898 
899 #endif
ZoneEvolutionQuantities
IDs for quantities saved as part of the evolution.
double tidal_torque_x(double above_fraction, Dissipation::QuantityEntry entry=Dissipation::NO_DERIV) const
Same as tidal_torque_x(bool, Dissipation::QuantityEntry) but below and above contributions mixed...
double m
The (m, m&#39;) coefficient.
double tidal_power(bool above, Dissipation::QuantityEntry entry=Dissipation::NO_DERIV) const
The dimensionless tidal power or one of its derivatives.
unsigned locked_zone_index() const
The index of this zone in the list of locked zones (valid only if locked).
Age derivative of MOMENT_OF_INERTIA.
virtual void spin_jumped()
Notifies the zone that its spin just jumped discontinously.
unsigned __locked_zone_index
If this zone is locked, this is its index in the list of locked zones in the system.
Inclination of the zone.
The rate at which periapsis changes.
const SpinOrbitLockInfo & lock_monitored(bool other=false) const
Return either of the locks being monitored.
double angular_momentum() const
The angular momentum of the given zone in .
The total number of quantities whose evolution is tracked.
virtual void reached_critical_age(double)
Change the body as necessary at the given age.
Declares a class for orientations of zones of DissipatingBody objects.
double __spin_frequency
The current spin frequency of the zone.
std::ostream & operator<<(std::ostream &os, const ZoneEvolutionQuantities &evol_var)
More civilized output for EvolVarType variables.
Declares a class for a stopping condition monitoring when a locked zone loses the lock...
unsigned __expansion_order
The tidal potential expansion order to use.
The rate at which the the inclination changes.
std::vector< std::list< double > > __evolution_real
The floating point quantities whose evolution is tracked.
Outer radius boundary of the zone.
virtual double next_stop_age() const
The next age when the evolution needs to be stopped for a change in one of the bodies.
double tidal_power(double above_fraction, Dissipation::QuantityEntry entry=Dissipation::NO_DERIV) const
Same as tidal_power(bool, Dissipation::QuantityEntry), but using the predefined mix of below/above co...
Orientations of zones of bodies in a binary system.
Number of real values evolution quantities.
void initializing(bool flag)
Notify the zone that it is in the process of initializing or not.
double tidal_torque_y(bool above, Dissipation::QuantityEntry entry=Dissipation::NO_DERIV) const
The dimensionless torque along y.
Eccentricity expansion order.
First age derivative of OUTER_MASS.
double m_minus_one
The (m-1, m&#39;) coefficient.
Periapsis of the zone.
A layer of a system body for which the tidal bulge is not exactly in phase with the tidal potential...
Declare an interface for evaluating the expansion of the tidal potential.
virtual unsigned expansion_order() const
Defines the SpinOrbitLockInfo class.
double m_plus_one
The (m+1, m&#39;) coefficient.
double modified_phase_lag(const EvolvingStar *star, unsigned zone_index, int orbital_frequency_multiplier, int spin_frequency_multiplier, double forcing_frequency, int entry, double *above_lock_value)
See Evolve::BrokenPowerlawPhaseLagZone::modified_phase_lag for details.
Definition: CInterface.cpp:107
TidalPotentialTerms __potential_term
The expansion of the tidal potential in series.
SpinOrbitLockInfo __other_lock
The term closest matched by the current spin-orbit ratio in the other direction from __lock...
Declaration of enumerations of dissipation quantities and derivatives.
double tidal_torque_y(double above_fraction, Dissipation::QuantityEntry entry=Dissipation::NO_DERIV) const
Same as tidal_torque_y(bool, Dissipation::QuantityEntry) but below and above contributions mixed...
For locked zones this is the orbital frequency multiple of the lock.
END_DIMENSIONLESS_DERIV
Moment of inertia of the zone.
void set_evolution_rates(double angular_momentum, double inclination, double periapsis)
Set evolution rates for this zone&#39;s properties for storing in the eveloution.
void set_reference_zone_angmom(double reference_angmom)
Defines the angular momentum of the reference zone for single body evolution.
double tidal_torque_z(double above_fraction, Dissipation::QuantityEntry entry=Dissipation::NO_DERIV) const
Same as tidal_torque_z(bool, Dissipation::QuantityEntry) but below and above contributions mixed...
virtual bool locked(int orbital_frequency_multiplier, int spin_frequency_multiplier) const
Should return true iff the given term is presently locked.
const SpinOrbitLockInfo & lock_held() const
The currntly held lock.
Outer mass boundary of the zone.
void set_lock(int orbital_frequency_multiplier, int spin_frequency_multiplier)
Locks the zone spin to the orbit in the given ratio.
NO_DERIV
The quantity itself, undifferentiated.
const std::list< int > & get_evolution_integer(ZoneEvolutionQuantities quantity) const
The tabulated evolution of an integer quantity so far.
Second age deriv of OUTER_RADIUS.
std::vector< std::list< int > > __evolution_integer
The integer quantities whose evolution is tracked.
double tidal_torque_z(bool above, Dissipation::QuantityEntry entry=Dissipation::NO_DERIV) const
The dimensionless tidal torque along z.
const std::list< double > & get_evolution_real(ZoneEvolutionQuantities quantity) const
The tabulated evolution of a real valued quantity so far.
Angular momentum of the zone.
First age deriv of OUTER_RADIUS.
Age second deriv of MOMENT_OF_INERTIA.
std::valarray< double > __torque_z
The dimensionless tidal torque in the z direction and its derivatives.
Declares a class for a stopping condition that combines other stopping conditions.
The rate at which angular momentum changes.
A class combining the the outputs of multiple stopping conditions.
bool __initializing
Is the zone in the middle of initializing (disable lock check)?
double tidal_torque_x(bool above, Dissipation::QuantityEntry entry=Dissipation::NO_DERIV) const
The dimensionless tidal torque along x.
For locked zones this is the spin frequency multiple of the lock.
virtual bool locked() const
Should return true iff any tidal term is locked.
Describes a system of two bodies orbiting each other.
Definition: BinarySystem.h:57
void set_lock(int orbital_freq_mult, int spin_freq_mult, short lock_direction=0)
Define which tidal dissipation term is in a lock.
unsigned & locked_zone_index()
Reference to the locked_zone_index() of this zone.
double spin_frequency() const
The spin frequency of the given zone.
Defines a lock between the spin of a dissipating body and the orbit.
Declares a stopping condition monitoring spin-orbit synchronization.