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:
135  unsigned __e_order;
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 
174  std::valarray<double> __power,
175 
180  __torque_x,
181 
186  __torque_y,
187 
192  __torque_z;
193 
199 
202  __other_lock;
203 
205  std::vector< std::list<double> > __evolution_real;
206 
208  std::vector< std::list<int> > __evolution_integer;
209 
213 
216 
223  void fix_forcing_frequency(
225  const SpinOrbitLockInfo &limit,
226 
229  int orbital_frequency_multiplier,
230 
233  int spin_frequency_multiplier,
234 
237  double &forcing_frequency
238  ) const;
239 
244  void update_lock_to_lower_e_order(SpinOrbitLockInfo &lock);
245 
248  void limit_above_lock_per_expansion_order(
249  int proposed_orbital_multiplier,
250  int proposed_spin_multiplier
251  );
252 
255  void set_faster_spin_lock(
261  int proposed_orbital_multiplier,
262 
268  int proposed_spin_multiplier
269  );
270 
275  void initialize_locks();
276 
278  void add_tidal_term(
280  int m,
281 
283  int mp,
284 
286  double tidal_frequency,
287 
291  const TidalTermTriplet &U_value,
292 
294  const TidalTermTriplet &U_i_deriv,
295 
297  const TidalTermTriplet &U_e_deriv,
298 
301  const TidalTermTriplet &U_error
302  );
303 
306  virtual void check_locks_consistency() const;
307 
308  protected:
310  void initializing(bool flag) {__initializing = flag;}
311 
313  void configure_spin(
315  double spin,
316 
318  bool spin_is_frequency
319  );
320 
321  public:
322  DissipatingZone();
323 
326  virtual void configure(
328  bool initialize,
329 
331  double age,
332 
334  double orbital_frequency,
335 
337  double eccentricity,
338 
340  double orbital_angmom,
341 
344  double spin,
345 
347  double inclination,
348 
351  double periapsis,
352 
355  bool spin_is_frequency
356  );
357 
362  double angular_momentum,
363 
365  double inclination,
366 
368  double periapsis
369  )
370  {
371  __angular_momentum_evolution_rate = angular_momentum;
372  ZoneOrientation::set_evolution_rates(inclination, periapsis);
373  }
374 
380  double forcing_frequency(
383  int orbital_frequency_multiplier,
384 
387  int spin_frequency_multiplier,
388 
390  double orbital_frequency
391  ) const;
392 
395  void set_reference_zone_angmom(double reference_angmom)
396  {__orbital_angmom=reference_angmom;}
397 
403  double periapsis_evolution(
406  const Eigen::Vector3d &orbit_torque,
407 
411  const Eigen::Vector3d &zone_torque,
412 
420  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV,
421 
425  const Eigen::Vector3d &orbit_torque_deriv=
426  Eigen::Vector3d(),
427 
431  const Eigen::Vector3d &zone_torque_deriv=Eigen::Vector3d()
432  );
433 
439  double inclination_evolution(
442  const Eigen::Vector3d &orbit_torque,
443 
447  const Eigen::Vector3d &zone_torque,
448 
463  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV,
464 
468  const Eigen::Vector3d &orbit_torque_deriv=Eigen::Vector3d(),
469 
473  const Eigen::Vector3d &zone_torque_deriv=Eigen::Vector3d()
474  );
475 
476 
478  virtual bool locked(int orbital_frequency_multiplier,
479  int spin_frequency_multiplier) const
480  {return __lock(orbital_frequency_multiplier,
481  spin_frequency_multiplier);}
482 
484  virtual bool locked() const
485  {return __lock;}
486 
488  const SpinOrbitLockInfo &lock_held() const {return __lock;}
489 
492  void release_lock();
493 
495  void release_lock(
497  short direction
498  );
499 
501  void set_lock(int orbital_frequency_multiplier,
502  int spin_frequency_multiplier)
503  {
504  assert(!__lock);
505  __lock.set_lock(orbital_frequency_multiplier,
506  spin_frequency_multiplier);
507  }
508 
517  virtual double modified_phase_lag(
520  int orbital_frequency_multiplier,
521 
524  int spin_frequency_multiplier,
525 
527  double forcing_frequency,
528 
533  Dissipation::QuantityEntry entry,
534 
538  double &above_lock_value) const =0;
539 
542  virtual double love_coefficient(
545  int orbital_frequency_multiplier,
546 
549  int spin_frequency_multiplier,
550 
555  Dissipation::QuantityEntry entry
556  ) const =0;
557 
560  virtual double moment_of_inertia(
566  int deriv_order=0
567  ) const =0;
568 
571  virtual double moment_of_inertia(
573  double age,
574 
580  int deriv_order=0
581  ) const =0;
582 
584  double spin_frequency() const {return __spin_frequency;}
585 
587  double angular_momentum() const {return __angular_momentum;}
588 
590  double tidal_power(
595  bool above,
596 
598  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
599  ) const
600  {
601  if(entry == Dissipation::EXPANSION_ERROR)
603 
604  assert(entry <= Dissipation::END_DIMENSIONLESS_DERIV);
605  assert(2 * entry + 1 < static_cast<int>(__power.size()));
606 
607  return __power[2 * entry + (above? 1 : 0)];
608  }
609 
612  double tidal_power(
615  double above_fraction,
616 
618  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
619  ) const
620  {
621 
622  if(entry == Dissipation::EXPANSION_ERROR)
624 
625  assert(!locked() || (above_fraction >= 0 && above_fraction <= 1));
626  assert(entry <= Dissipation::END_DIMENSIONLESS_DERIV);
627  assert(2 * entry + 1 < static_cast<int>(__power.size()));
628 
629  return (
630  above_fraction * __power[2 * entry + 1]
631  +
632  (1.0 - above_fraction) * __power[2 * entry]
633  );
634  }
635 
640  bool above,
641  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
642  ) const
643  {
644  if(entry == Dissipation::EXPANSION_ERROR)
646 
647  assert(entry <= Dissipation::END_DIMENSIONLESS_DERIV);
648  assert(2 * entry + 1 < static_cast<int>(__torque_x.size()));
649 
650  return __torque_x[2 * entry + (above ? 1 : 0)];
651  }
652 
658  double above_fraction,
659 
662  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
663  ) const
664  {
665  if(entry == Dissipation::EXPANSION_ERROR)
667 
668  assert(
669  !locked() || (above_fraction >= 0 && above_fraction <= 1)
670  );
671  assert(entry <= Dissipation::END_DIMENSIONLESS_DERIV);
672  assert(
673  2 * entry + 1
674  <
675  static_cast<int>(__torque_x.size())
676  );
677 
678  return (above_fraction * __torque_x[2 * entry + 1]
679  +
680  (1.0 - above_fraction) * __torque_x[2 * entry]);
681  }
682 
687  bool above,
688  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
689  ) const
690  {
691  if(entry == Dissipation::EXPANSION_ERROR)
693 
694  assert(entry <= Dissipation::END_DIMENSIONLESS_DERIV);
695  assert(
696  2 * entry + 1
697  <
698  static_cast<int>(__torque_y.size())
699  );
700 
701  return __torque_y[2 * entry + (above? 1 : 0)];
702  }
703 
709  double above_fraction,
710 
713  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
714  ) const
715  {
716  if(entry == Dissipation::EXPANSION_ERROR)
718 
719  assert(!locked() || (above_fraction >= 0 && above_fraction <= 1));
720  assert(entry <= Dissipation::END_DIMENSIONLESS_DERIV);
721  assert(2 * entry + 1 < static_cast<int>(__torque_y.size()));
722 
723  return (above_fraction * __torque_y[2 * entry + 1]
724  +
725  (1.0 - above_fraction) * __torque_y[2 * entry]);
726  }
727 
732  bool above,
733  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
734  ) const
735  {
736  if(entry == Dissipation::EXPANSION_ERROR)
738 
739  assert(entry <= Dissipation::END_DIMENSIONLESS_DERIV);
740  assert(2 * entry + 1 < static_cast<int>(__torque_z.size()));
741 
742  return __torque_z[2 * entry + (above? 1 : 0)];
743  }
744 
750  double above_fraction,
751 
754  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
755  ) const
756  {
757  if(entry == Dissipation::EXPANSION_ERROR)
759 
760  assert(!locked() || (above_fraction >= 0 && above_fraction <= 1));
761  assert(entry < Dissipation::END_DIMENSIONLESS_DERIV);
762  assert(2 * entry + 1 < static_cast<int>(__torque_z.size()));
763 
764  return (above_fraction * __torque_z[2 * entry + 1]
765  +
766  (1.0 - above_fraction) * __torque_z[2 * entry]);
767  }
768 
770  //configure()).
774  virtual double outer_radius(
779  int deriv_order = 0
780  ) const =0;
781 
784  virtual double outer_radius(double age, int deriv_order=0) const =0;
785 
791  virtual double outer_mass(
796  int deriv_order=0
797  ) const =0;
798 
801  virtual double outer_mass(double age, int deriv_order=0) const =0;
802 
805  virtual unsigned eccentricity_order() const {return __e_order;}
806 
808  virtual void change_e_order(
810  unsigned new_e_order,
811 
813  BinarySystem &system,
814 
816  bool primary,
817 
819  unsigned zone_index
820  );
821 
823  virtual void add_to_evolution();
824 
826  virtual void rewind_evolution(
828  unsigned nsteps
829  );
830 
832  virtual void reset_evolution();
833 
835  const std::list<double> &get_evolution_real(
836  ZoneEvolutionQuantities quantity
837  ) const
838  {
839  assert(quantity < NUM_REAL_EVOL_QUANTITIES);
840 
841  return __evolution_real[quantity];
842  }
843 
845  const std::list<int> &get_evolution_integer(
846  ZoneEvolutionQuantities quantity
847  ) const
848  {
849  assert(quantity >= NUM_REAL_EVOL_QUANTITIES);
850 
851  return __evolution_integer[quantity - NUM_REAL_EVOL_QUANTITIES];
852  }
853 
854 
857  unsigned locked_zone_index() const
858  {
859  assert(__lock);
860 
861  return __locked_zone_index;
862  }
863 
865  unsigned &locked_zone_index()
866  {
867  assert(__lock);
868 
869  return __locked_zone_index;
870  }
871 
873  virtual bool dissipative() const =0;
874 
877  virtual bool can_lock() const =0;
878 
883  virtual CombinedStoppingCondition *stopping_conditions(
885  BinarySystem &system,
886 
888  bool primary,
889 
891  unsigned zone_index
892  );
893 
895  virtual void spin_jumped()
896  {initialize_locks();}
897 
901  virtual void reached_critical_age(double)
902  {assert(false);}
903 
906  virtual double next_stop_age() const
907  {return Core::Inf;}
908 
910  const SpinOrbitLockInfo &lock_monitored(bool other=false) const
911  {
912  if(other)
913  return __other_lock;
914  else
915  return __lock;
916  }
917  }; //End DissipatingZone class.
918 
919 } //End Evolve namespace.
920 
921 #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
Useful for debugging.
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...
The rate at which the the inclination changes.
unsigned __e_order
The expansion order in eccentricity to use.
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.
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...
virtual unsigned eccentricity_order() const
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:56
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.