Planetary Orbital Evolution due to Tides
Orbital evolution of two objects experiencing tides
BinarySystem.h
Go to the documentation of this file.
1 
8 #ifndef __BINARY_SYSTEM_H
9 #define __BINARY_SYSTEM_H
10 
11 #include "../Core/SharedLibraryExportMacros.h"
12 #include "DissipatingBody.h"
15 #include "../Core/AstronomicalConstants.h"
16 #include "../Core/Common.h"
17 #include "../Core/OrbitalExpressions.h"
18 #include "../Core/Error.h"
19 #include <gsl/gsl_errno.h>
20 #include <gsl/gsl_odeiv2.h>
21 #include <gsl/gsl_siman.h>
22 #include <string>
23 #include <limits>
24 #include <iostream>
25 #include <iomanip>
26 
27 namespace Evolve {
28 
57  class LIB_PUBLIC BinarySystem {
58  private:
60  std::string __name;
61 
62  std::list<double>
65  __semimajor_evolution,
66 
69  __eccentricity_evolution,
70 
72  //currently recorded step.
74 
76  //currently recorded step.
77  __eccentricity_rate_evolution;
78 
79  double
81  __age,
82 
85 
87  __eccentricity,
88 
90  __orbital_energy,
91 
93  __orbital_angmom,
94 
96  __orbit_power,
97 
100 
101  __orbit_angmom_gain;
102 
103  mutable double
106 
108  __eccentricity_rate;
109 
112  Eigen::Vector3d __orbit_torque;
113 
116 
118  std::list<unsigned> __locked_zones;
119 
125  std::valarray<Eigen::VectorXd> __above_lock_fractions,
126 
129  __above_lock_fractions_inclination_deriv,
130 
134 
137  __above_lock_fractions_inertia_deriv,
138 
141  __above_lock_fractions_angmom_deriv;
142 
149 
154  Eigen::ColPivHouseholderQR<Eigen::MatrixXd>
156 
163  &__body1,
164 
169  &__body2;
170 
171  typedef
172  std::list< std::tuple<unsigned, short, double> >
173  lock_scenario_type;
174 
175 #ifndef NDEBUG
176  //initialize_locks()
178  lock_scenario_type __selected_lock_scenario;
179 #endif
180 
182  void find_locked_zones();
183 
198  lock_scenario_type find_synchronized_zones(
201  double precision
202  );
203 
208  void set_lock_scenario(
212  const lock_scenario_type &lock_scenario
213  );
214 
216  void unlock_all_zones(
218  const std::vector<short> &unlock_directions,
219 
224  const std::vector<double> &original_angmom = std::vector<double>()
225  );
226 
229  bool test_synchronized_unlocked_zone(
232  unsigned test_zone_ind
233  );
234 
235 #ifndef NDEBUG
236  void describe_lock_scenario(
238  std::ostream &os,
239 
242  const lock_scenario_type &lock_scenario,
243 
246  const std::vector<bool> passed,
247 
249  bool add_header=false
250  );
251 #endif
252 
255  bool test_lock_scenario(
258  const lock_scenario_type &lock_scenario
259 #ifndef NDEBUG
261  , bool first_scenario
262 #endif
263  );
264 
269  bool explore_lock_scenarios(
272  lock_scenario_type::const_iterator next_synchronized_zone,
273 
275  unsigned num_synchronized_zones,
276 
278  lock_scenario_type &lock_scenario
279 
280 #ifndef NDEBUG
282  , bool first_scenario = true
283 #endif
284  );
285 
291  int locked_surface_differential_equations(
293  double *evolution_rates
294  ) const;
295 
296 #ifdef ENABLE_DERIVATIVES
297  void locked_surface_jacobian(
304  double *param_derivs,
305 
308  double *age_derivs
309  ) const;
310 #endif
311 
316  int single_body_differential_equations(
319  double *evolution_rates
320  ) const;
321 
322 #ifdef ENABLE_DERIVATIVES
323  void fill_single_body_jacobian(
327  double *inclination_param_derivs,
328 
330  double *periapsis_param_derivs,
331 
334  double *angmom_param_derivs,
335 
338  double *inclination_age_derivs,
339 
342  double *periapsis_age_derivs,
343 
346  double *angmom_age_derivs
347  ) const;
348 
354  void single_body_jacobian(
356  double *param_derivs,
357 
360  double *age_derivs
361  ) const;
362 #endif
363 
374  double semimajor_evolution(
378  double orbit_power,
379 
383  double orbit_power_deriv=Core::NaN
384  ) const;
385 
396  double eccentricity_evolution(
398  double orbit_power,
399 
403  double orbit_angmom_gain,
404 
407  //eccentricity is returned instead of the rate itself. In this
410  double orbit_power_deriv=Core::NaN,
411 
415  double orbit_angmom_gain_deriv=Core::NaN,
416 
419  bool semimajor_deriv=true
420  ) const;
421 
424  void above_lock_problem_deriv_correction(
426  Dissipation::QuantityEntry entry,
427 
430  bool body1_deriv,
431 
433  Eigen::MatrixXd &matrix,
434 
436  Eigen::VectorXd &rhs
437  ) const;
438 
446  void calculate_above_lock_fractions(
448  Eigen::VectorXd &fractions,
449 
453  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV,
454 
458  bool body1_deriv=true
459  );
460 
463  Eigen::VectorXd above_lock_fractions_deriv(
466  Dissipation::QuantityEntry entry,
467 
470  DissipatingBody &body,
471 
474  unsigned zone_index
475  );
476 
478  void fill_above_lock_fractions_deriv();
479 
486  void update_above_lock_fractions();
487 
492  void fill_orbit_torque_and_power();
493 
494 
499  int binary_differential_equations(
502  double *differential_equations
503  ) const;
504 
505 
512  template<typename VALUE_TYPE>
513  void add_body_rate_deriv(
515  const DissipatingBody &body,
516 
519  VALUE_TYPE (DissipatingBody::*func)(Dissipation::QuantityEntry,
520  unsigned,
521  const Eigen::VectorXd &) const,
522 
525  std::valarray<VALUE_TYPE> &orbit_rate_deriv,
526 
529  unsigned offset
530  ) const;
531 
534  void fill_orbit_power_deriv(
536  std::valarray<double> &orbit_power_deriv
537  ) const;
538 
541  void fill_orbit_angmom_gain_deriv(
543  std::valarray<double> &orbit_angmom_gain_deriv
544  ) const;
545 
546 #ifdef ENABLE_DERIVATIVES
547  void semimajor_jacobian(
551  const std::valarray<double> &orbit_power_deriv,
552 
554  bool a6p5,
555 
558  double *param_derivs,
559 
562  double &age_deriv
563  ) const;
564 
566  void eccentricity_jacobian(
569  const std::valarray<double> &orbit_power_deriv,
570 
573  const std::valarray<double> &orbit_angmom_gain_deriv,
574 
576  bool a6p5,
577 
580  double *param_derivs,
581 
584  double &age_deriv
585  ) const;
586 
589  void angle_evolution_age_deriv(
591  DissipatingBody &body,
592 
595  unsigned zone_ind,
596 
598  double sin_inc,
599 
601  double cos_inc,
602 
605  unsigned locked_zone_ind,
606 
609  double &inclination,
610 
613  double &periapsis
614  ) const;
615 
618  void angle_evolution_orbit_deriv(
621  Dissipation::QuantityEntry entry,
622 
624  double angmom_deriv,
625 
627  DissipatingBody &body,
628 
630  unsigned zone_ind,
631 
633  double sin_inc,
634 
636  double cos_inc,
637 
640  unsigned locked_zone_ind,
641 
644  double &inclination,
645 
647  double &periapsis
648  ) const;
649 
650  void fill_orbit_torque_deriv(
654  Dissipation::QuantityEntry entry,
655 
658  DissipatingBody &body,
659 
662  unsigned zone_ind,
663 
668  std::valarray<Eigen::Vector3d> &orbit_torque_deriv
669  ) const;
670 
673  void fill_zone_torque_deriv(
677  Dissipation::QuantityEntry entry,
678 
680  DissipatingBody &body,
681 
683  unsigned zone_ind,
684 
692  std::valarray<Eigen::Vector3d> &zone_torque_deriv
693  ) const;
694 
697  void inclination_evolution_zone_derivs(
701  Dissipation::QuantityEntry entry,
702 
704  DissipatingBody &body,
705 
707  unsigned zone_ind,
708 
711  double zone_x_torque_above,
712 
715  double zone_x_torque_below,
716 
718  const std::valarray<Eigen::Vector3d> &zone_torque_deriv,
719 
722  const Eigen::Vector3d &orbit_torque,
723 
725  const std::valarray<Eigen::Vector3d> &orbit_torque_deriv,
726 
728  const std::valarray<Eigen::VectorXd> &above_frac_deriv,
729 
731  double sin_inc,
732 
734  double cos_inc,
735 
738  unsigned locked_zone_ind,
739 
741  double *result
742  ) const;
743 
746  void periapsis_evolution_zone_derivs(
748  Dissipation::QuantityEntry entry,
749 
751  DissipatingBody &body,
752 
754  unsigned zone_ind,
755 
758  double zone_y_torque_above,
759 
762  double zone_y_torque_below,
763 
765  const std::valarray<Eigen::Vector3d> &zone_torque_deriv,
766 
768  double orbit_y_torque,
769 
771  const std::valarray<Eigen::Vector3d> &orbit_torque_deriv,
772 
774  const std::valarray<Eigen::VectorXd> &above_frac_deriv,
775 
777  double sin_inc,
778 
780  double cos_inc,
781 
784  unsigned locked_zone_ind,
785 
787  double *result
788  ) const;
789 
790  void spin_angmom_evolution_zone_derivs(
792  Dissipation::QuantityEntry entry,
793 
795  DissipatingBody &body,
796 
798  unsigned zone_ind,
799 
802  double zone_z_torque_above,
803 
806  double zone_z_torque_below,
807 
809  const std::valarray<Eigen::Vector3d> &zone_torque_deriv,
810 
812  const std::valarray<Eigen::VectorXd> &above_frac_deriv,
813 
816  unsigned locked_zone_ind,
817 
819  double *result
820  ) const;
821 
823  void binary_jacobian(
825  double *param_derivs,
826 
829  double *age_derivs
830  ) const;
831 #endif
832 
834  void fill_locked_surface_orbit(std::valarray<double> &orbit) const;
835 
837  void fill_binary_orbit(std::valarray<double> &orbit) const;
838 
840  void fill_single_orbit(std::valarray<double> &orbit) const;
841 
842  public:
847  DissipatingBody &body1,
848 
851  DissipatingBody &body2,
852 
854  const std::string &system_name=""
855  ) :
856  __name(system_name),
857  __above_lock_fractions(Dissipation::NUM_DERIVATIVES),
858  __body1(body1),
859  __body2(body2)
860  {}
861 
863  const std::string get_name() const {return __name;}
864 
866  virtual int configure(
868  bool initialize,
869 
871  double age,
872 
874  double semimajor,
875 
877  double eccentricity,
878 
881  const double *spin_angmom,
882 
886  const double *inclination,
887 
891  const double *periapsis,
892 
894  Core::EvolModeType evolution_mode
895  );
896 
899  int configure(
901  bool initialize,
902 
904  double age,
905 
907  const double *parameters,
908 
910  Core::EvolModeType evolution_mode
911  );
912 
914  double age() const {return __age;}
915 
917  const DissipatingBody &primary() const {return __body1;}
918 
920  const DissipatingBody &secondary() const {return __body2;}
921 
923  unsigned number_zones() const
924  {return (__evolution_mode == Core::BINARY
925  ? __body1.number_zones() + __body2.number_zones()
926  : __body1.number_zones());}
927 
929  unsigned number_locked_zones() const
930  {return __body1.number_locked_zones() + __body2.number_locked_zones();}
931 
933  double semimajor() const {return __semimajor;}
934 
936  double eccentricity() const {return __eccentricity;}
937 
940  double orbital_frequency(bool semimajor_deriv=false) const
941  {
942  return Core::orbital_angular_velocity(__body1.mass(),
943  __body2.mass(),
944  __semimajor,
945  semimajor_deriv);
946  }
947 
952  Core::EvolModeType fill_orbit(
954  std::valarray<double> &orbit
955  ) const;
956 
957 
960  double above_lock_fraction(
962  unsigned locked_zone_index,
963 
968  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV,
969 
972  unsigned deriv_zone_index=0,
973 
976  bool secondary_radius=false
977  );
978 
986  int differential_equations(
988  double age,
989 
1016  const double *parameters,
1017 
1019  Core::EvolModeType evolution_mode,
1020 
1024  double *differential_equations
1025  );
1026 
1027 #ifdef ENABLE_DERIVATIVES
1028  int jacobian(
1033  double age,
1034 
1036  const double *parameters,
1037 
1039  Core::EvolModeType evolution_mode,
1040 
1043  double *param_derivs,
1044 
1047  double *age_derivs
1048  );
1049 #endif
1050 
1053  void initialize_locks(
1057  double sync_precision
1058  );
1059 
1062  void check_for_lock(
1064  int orbital_freq_mult,
1065 
1068  int spin_freq_mult,
1069 
1071  unsigned short body_index,
1072 
1074  unsigned zone_index,
1075 
1078  short direction
1079  );
1080 
1087  virtual double minimum_separation(
1089  bool deriv=false
1090  ) const;
1091 
1093  Core::EvolModeType evolution_mode() {return __evolution_mode;}
1094 
1099  virtual void secondary_died();
1100 
1102  virtual void release_lock(
1105  unsigned locked_zone_index,
1106 
1109  short direction
1110  );
1111 
1113  virtual void add_to_evolution();
1114 
1116  virtual void reset_evolution();
1117 
1119  virtual void rewind_evolution(
1121  unsigned nsteps
1122  );
1123 
1128  virtual CombinedStoppingCondition *stopping_conditions();
1129 
1134  virtual void reached_critical_age(double age);
1135 
1138  virtual double next_stop_age() const;
1139 
1141  const std::list<double> &semimajor_evolution() const
1142  {return __semimajor_evolution;}
1143 
1145  const std::list<double> &semimajor_evolution_rate() const
1146  {return __semimajor_rate_evolution;}
1147 
1149  const std::list<double> &eccentricity_evolution() const
1150  {return __eccentricity_evolution;}
1151 
1153  const std::list<double> &eccentricity_evolution_rate() const
1154  {return __eccentricity_rate_evolution;}
1155 
1159  unsigned new_expansion_order
1160  )
1161  {
1162  __body1.change_expansion_order(new_expansion_order, *this, true);
1163  __body2.change_expansion_order(new_expansion_order, *this, false);
1164  }
1165 
1168  virtual unsigned expansion_order() const;
1169 
1170  virtual ~BinarySystem() {}
1171 
1172  }; //End BinarySystem class.
1173 
1174 } //End Evolve namespace.
1175 
1176 #endif
Eigen::VectorXd __above_lock_fractions_body2_radius_deriv
The derivative of the above lock fractions w.r.t. to the radius of the secondardy.
Definition: BinarySystem.h:148
const std::list< double > & eccentricity_evolution() const
The tabulated evolution of the eccentricity so far.
const std::string get_name() const
Returns the name of the system.
Definition: BinarySystem.h:863
Eigen::Vector3d __orbit_torque
The torque on the orbit in the coordinate system of the outermost zone of the first body...
Definition: BinarySystem.h:112
double __semimajor_rate
The current rate at which the semiamjor axis is changing.
Definition: BinarySystem.h:105
const DissipatingBody & primary() const
Returns the primary body in the system (const).
Definition: BinarySystem.h:917
A base class for any body contributing to tidal dissipation.
std::string __name
The name of the binary system (e.g. "HAT-P-20")
Definition: BinarySystem.h:60
double __semimajor
The current semimajor axis.
Definition: BinarySystem.h:81
const std::list< double > & eccentricity_evolution_rate() const
The tabulated evolution of the eccentricity so far.
Orientations of zones of bodies in a binary system.
const std::list< double > & semimajor_evolution() const
The tabulated evolution of the semimajor axis so far.
lock_scenario_type __selected_lock_scenario
The lock/unlock configuration selected by the last call to.
Definition: BinarySystem.h:178
NUM_DERIVATIVES
The total number of derivatives supported.
double age() const
Returns the present age of the system in Gyr.
Definition: BinarySystem.h:914
unsigned number_locked_zones() const
How many zones on either body are currently locked.
Definition: BinarySystem.h:929
const DissipatingBody & secondary() const
Returns the secondary body in the system (const).
Definition: BinarySystem.h:920
std::list< double > __semimajor_rate_evolution
The rate at which the semimajor axis evolved at each.
Definition: BinarySystem.h:65
DissipatingBody & __body2
The second body in the system.
Definition: BinarySystem.h:163
BinarySystem(DissipatingBody &body1, DissipatingBody &body2, const std::string &system_name="")
Construct a binary system.
Definition: BinarySystem.h:844
std::list< unsigned > __locked_zones
A list of indices of locked zones.
Definition: BinarySystem.h:118
Core::EvolModeType __evolution_mode
The evolution mode from the last call to configure();.
Definition: BinarySystem.h:115
Eigen::ColPivHouseholderQR< Eigen::MatrixXd > __above_lock_fractions_decomp
The matrix that defines the problem to solve for __above_lock_fractions.
Definition: BinarySystem.h:155
double orbital_frequency(bool semimajor_deriv=false) const
The current orbital frequency [Rad/day] (calculated from the semimajor axis).
Definition: BinarySystem.h:940
Declares a stopping condition class monitoring for the death of the secondary object.
Core::EvolModeType evolution_mode()
The evolution mode of last call to configure().
NO_DERIV
The quantity itself, undifferentiated.
Declares the DissipatingBody class.
EvolModeType
The various evolution modes.
Definition: Common.h:42
double semimajor() const
The current semimajor axis of the system.
Definition: BinarySystem.h:933
const std::list< double > & semimajor_evolution_rate() const
The tabulated evolution of the semimajor axis so far.
Declares a class for a stopping condition that combines other stopping conditions.
std::valarray< Eigen::VectorXd > __above_lock_fractions_periapsis_deriv
The derivatives of the above lock fractions w.r.t. the periapses of the zones.
Definition: BinarySystem.h:125
virtual void change_expansion_order(unsigned new_expansion_order)
Change the tidal potential expansion order for all dissipative zones.
A class combining the the outputs of multiple stopping conditions.
unsigned number_zones() const
The total number of zones in both system bodies.
Definition: BinarySystem.h:923
double eccentricity() const
The current eccentricity of the system.
Definition: BinarySystem.h:936
Describes a system of two bodies orbiting each other.
Definition: BinarySystem.h:57