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 
26 namespace Evolve {
27 
56  class LIB_PUBLIC BinarySystem {
57  private:
59  std::string __name;
60 
61  std::list<double>
64  __semimajor_evolution,
65 
68  __eccentricity_evolution,
69 
71  //currently recorded step.
73 
75  //currently recorded step.
76  __eccentricity_rate_evolution;
77 
78  double
80  __age,
81 
84 
86  __eccentricity,
87 
89  __orbital_energy,
90 
92  __orbital_angmom,
93 
95  __orbit_power,
96 
99  __orbit_power_expansion_error,
100 
103  __orbit_angmom_gain,
104 
107  __orbit_angmom_gain_expansion_error;
108 
109  mutable double
112 
114  __eccentricity_rate;
115 
116  Eigen::Vector3d
119  __orbit_torque,
120 
124 
127 
129  std::list<unsigned> __locked_zones;
130 
136  std::valarray<Eigen::VectorXd> __above_lock_fractions,
137 
140  __above_lock_fractions_inclination_deriv,
141 
145 
148  __above_lock_fractions_inertia_deriv,
149 
152  __above_lock_fractions_angmom_deriv;
153 
160 
165  Eigen::ColPivHouseholderQR<Eigen::MatrixXd>
167 
174  &__body1,
175 
180  &__body2;
181 
183  void find_locked_zones();
184 
190  int locked_surface_differential_equations(
192  double *evolution_rates,
193 
197  bool expansion_error
198  ) const;
199 
205  void locked_surface_jacobian(
207  double *param_derivs,
208 
211  double *age_derivs
212  ) const;
213 
218  int single_body_differential_equations(
221  double *evolution_rates,
222 
226  bool expansion_error
227  ) const;
228 
230  void fill_single_body_jacobian(
233  double *inclination_param_derivs,
234 
236  double *periapsis_param_derivs,
237 
240  double *angmom_param_derivs,
241 
244  double *inclination_age_derivs,
245 
248  double *periapsis_age_derivs,
249 
252  double *angmom_age_derivs
253  ) const;
254 
260  void single_body_jacobian(
262  double *param_derivs,
263 
266  double *age_derivs
267  ) const;
268 
279  double semimajor_evolution(
283  double orbit_power,
284 
288  double orbit_power_deriv=Core::NaN
289  ) const;
290 
295  {return semimajor_evolution(__orbit_power_expansion_error);}
296 
307  double eccentricity_evolution(
309  double orbit_power,
310 
314  double orbit_angmom_gain,
315 
318  //eccentricity is returned instead of the rate itself. In this
321  double orbit_power_deriv=Core::NaN,
322 
326  double orbit_angmom_gain_deriv=Core::NaN,
327 
330  bool semimajor_deriv=true
331  ) const;
332 
336  double eccentricity_evolution_expansion_error() const;
337 
340  void above_lock_problem_deriv_correction(
342  Dissipation::QuantityEntry entry,
343 
346  bool body1_deriv,
347 
349  Eigen::MatrixXd &matrix,
350 
352  Eigen::VectorXd &rhs
353  ) const;
354 
362  void calculate_above_lock_fractions(
364  Eigen::VectorXd &fractions,
365 
369  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV,
370 
374  bool body1_deriv=true
375  );
376 
379  Eigen::VectorXd above_lock_fractions_deriv(
382  Dissipation::QuantityEntry entry,
383 
386  DissipatingBody &body,
387 
390  unsigned zone_index
391  );
392 
394  void fill_above_lock_fractions_deriv();
395 
402  void update_above_lock_fractions();
403 
408  void fill_orbit_torque_and_power();
409 
410 
415  int binary_differential_equations(
418  double *differential_equations,
419 
423  bool expansion_error
424  ) const;
425 
426 
433  template<typename VALUE_TYPE>
434  void add_body_rate_deriv(
436  const DissipatingBody &body,
437 
440  VALUE_TYPE (DissipatingBody::*func)(Dissipation::QuantityEntry,
441  unsigned,
442  const Eigen::VectorXd &) const,
443 
446  std::valarray<VALUE_TYPE> &orbit_rate_deriv,
447 
450  unsigned offset
451  ) const;
452 
455  void fill_orbit_power_deriv(
457  std::valarray<double> &orbit_power_deriv
458  ) const;
459 
462  void fill_orbit_angmom_gain_deriv(
464  std::valarray<double> &orbit_angmom_gain_deriv
465  ) const;
466 
468  void semimajor_jacobian(
471  const std::valarray<double> &orbit_power_deriv,
472 
474  bool a6p5,
475 
478  double *param_derivs,
479 
482  double &age_deriv
483  ) const;
484 
486  void eccentricity_jacobian(
489  const std::valarray<double> &orbit_power_deriv,
490 
493  const std::valarray<double> &orbit_angmom_gain_deriv,
494 
496  bool a6p5,
497 
500  double *param_derivs,
501 
504  double &age_deriv
505  ) const;
506 
509  void angle_evolution_age_deriv(
511  DissipatingBody &body,
512 
515  unsigned zone_ind,
516 
518  double sin_inc,
519 
521  double cos_inc,
522 
525  unsigned locked_zone_ind,
526 
529  double &inclination,
530 
533  double &periapsis
534  ) const;
535 
538  void angle_evolution_orbit_deriv(
541  Dissipation::QuantityEntry entry,
542 
544  double angmom_deriv,
545 
547  DissipatingBody &body,
548 
550  unsigned zone_ind,
551 
553  double sin_inc,
554 
556  double cos_inc,
557 
560  unsigned locked_zone_ind,
561 
564  double &inclination,
565 
567  double &periapsis
568  ) const;
569 
570  void fill_orbit_torque_deriv(
574  Dissipation::QuantityEntry entry,
575 
578  DissipatingBody &body,
579 
582  unsigned zone_ind,
583 
588  std::valarray<Eigen::Vector3d> &orbit_torque_deriv
589  ) const;
590 
593  void fill_zone_torque_deriv(
597  Dissipation::QuantityEntry entry,
598 
600  DissipatingBody &body,
601 
603  unsigned zone_ind,
604 
612  std::valarray<Eigen::Vector3d> &zone_torque_deriv
613  ) const;
614 
617  void inclination_evolution_zone_derivs(
621  Dissipation::QuantityEntry entry,
622 
624  DissipatingBody &body,
625 
627  unsigned zone_ind,
628 
631  double zone_x_torque_above,
632 
635  double zone_x_torque_below,
636 
638  const std::valarray<Eigen::Vector3d> &zone_torque_deriv,
639 
642  const Eigen::Vector3d &orbit_torque,
643 
645  const std::valarray<Eigen::Vector3d> &orbit_torque_deriv,
646 
648  const std::valarray<Eigen::VectorXd> &above_frac_deriv,
649 
651  double sin_inc,
652 
654  double cos_inc,
655 
658  unsigned locked_zone_ind,
659 
661  double *result
662  ) const;
663 
666  void periapsis_evolution_zone_derivs(
668  Dissipation::QuantityEntry entry,
669 
671  DissipatingBody &body,
672 
674  unsigned zone_ind,
675 
678  double zone_y_torque_above,
679 
682  double zone_y_torque_below,
683 
685  const std::valarray<Eigen::Vector3d> &zone_torque_deriv,
686 
688  double orbit_y_torque,
689 
691  const std::valarray<Eigen::Vector3d> &orbit_torque_deriv,
692 
694  const std::valarray<Eigen::VectorXd> &above_frac_deriv,
695 
697  double sin_inc,
698 
700  double cos_inc,
701 
704  unsigned locked_zone_ind,
705 
707  double *result
708  ) const;
709 
710  void spin_angmom_evolution_zone_derivs(
712  Dissipation::QuantityEntry entry,
713 
715  DissipatingBody &body,
716 
718  unsigned zone_ind,
719 
722  double zone_z_torque_above,
723 
726  double zone_z_torque_below,
727 
729  const std::valarray<Eigen::Vector3d> &zone_torque_deriv,
730 
732  const std::valarray<Eigen::VectorXd> &above_frac_deriv,
733 
736  unsigned locked_zone_ind,
737 
739  double *result
740  ) const;
741 
743  void binary_jacobian(
745  double *param_derivs,
746 
749  double *age_derivs
750  ) const;
751 
753  void fill_locked_surface_orbit(std::valarray<double> &orbit) const;
754 
756  void fill_binary_orbit(std::valarray<double> &orbit) const;
757 
759  void fill_single_orbit(std::valarray<double> &orbit) const;
760 
761  public:
766  DissipatingBody &body1,
767 
770  DissipatingBody &body2,
771 
773  const std::string &system_name=""
774  ) :
775  __name(system_name),
776  __above_lock_fractions(Dissipation::NUM_DERIVATIVES),
777  __body1(body1),
778  __body2(body2)
779  {}
780 
782  const std::string get_name() const {return __name;}
783 
785  virtual int configure(
787  bool initialize,
788 
790  double age,
791 
793  double semimajor,
794 
796  double eccentricity,
797 
800  const double *spin_angmom,
801 
805  const double *inclination,
806 
810  const double *periapsis,
811 
813  Core::EvolModeType evolution_mode
814  );
815 
818  int configure(
820  bool initialize,
821 
823  double age,
824 
826  const double *parameters,
827 
829  Core::EvolModeType evolution_mode
830  );
831 
833  double age() const {return __age;}
834 
836  const DissipatingBody &primary() const {return __body1;}
837 
839  const DissipatingBody &secondary() const {return __body2;}
840 
842  unsigned number_zones() const
843  {return (__evolution_mode == Core::BINARY
844  ? __body1.number_zones() + __body2.number_zones()
845  : __body1.number_zones());}
846 
848  unsigned number_locked_zones() const
849  {return __body1.number_locked_zones() + __body2.number_locked_zones();}
850 
852  double semimajor() const {return __semimajor;}
853 
855  double eccentricity() const {return __eccentricity;}
856 
861  Core::EvolModeType fill_orbit(
863  std::valarray<double> &orbit
864  ) const;
865 
866 
869  double above_lock_fraction(
871  unsigned locked_zone_index,
872 
877  Dissipation::QuantityEntry entry=Dissipation::NO_DERIV,
878 
881  unsigned deriv_zone_index=0,
882 
885  bool secondary_radius=false
886  );
887 
895  int differential_equations(
897  double age,
898 
925  const double *parameters,
926 
928  Core::EvolModeType evolution_mode,
929 
933  double *differential_equations,
934 
938  bool expansion_error=false
939  );
940 
944  int jacobian(
946  double age,
947 
949  const double *parameters,
950 
952  Core::EvolModeType evolution_mode,
953 
956  double *param_derivs,
957 
960  double *age_derivs
961  );
962 
965  void check_for_lock(
967  int orbital_freq_mult,
968 
971  int spin_freq_mult,
972 
974  unsigned short body_index,
975 
977  unsigned zone_index,
978 
981  short direction
982  );
983 
990  virtual double minimum_separation(
992  bool deriv=false
993  ) const;
994 
996  Core::EvolModeType evolution_mode() {return __evolution_mode;}
997 
1002  virtual void secondary_died();
1003 
1005  virtual void release_lock(
1008  unsigned locked_zone_index,
1009 
1012  short direction
1013  );
1014 
1016  virtual void add_to_evolution();
1017 
1019  virtual void reset_evolution();
1020 
1022  virtual void rewind_evolution(
1024  unsigned nsteps
1025  );
1026 
1031  virtual CombinedStoppingCondition *stopping_conditions();
1032 
1037  virtual void reached_critical_age(double age);
1038 
1041  virtual double next_stop_age() const;
1042 
1044  const std::list<double> &semimajor_evolution() const
1045  {return __semimajor_evolution;}
1046 
1048  const std::list<double> &semimajor_evolution_rate() const
1049  {return __semimajor_rate_evolution;}
1050 
1052  const std::list<double> &eccentricity_evolution() const
1053  {return __eccentricity_evolution;}
1054 
1056  const std::list<double> &eccentricity_evolution_rate() const
1057  {return __eccentricity_rate_evolution;}
1058 
1060  virtual void change_e_order(
1062  unsigned new_e_order
1063  )
1064  {
1065  __body1.change_e_order(new_e_order, *this, true);
1066  __body2.change_e_order(new_e_order, *this, false);
1067  }
1068 
1071  virtual unsigned eccentricity_order() const;
1072 
1073  virtual ~BinarySystem() {}
1074 
1075  }; //End BinarySystem class.
1076 
1077 } //End Evolve namespace.
1078 
1079 #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:159
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:782
double __semimajor_rate
The current rate at which the semiamjor axis is changing.
Definition: BinarySystem.h:111
const DissipatingBody & primary() const
Returns the primary body in the system (const).
Definition: BinarySystem.h:836
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:59
double __semimajor
The current semimajor axis.
Definition: BinarySystem.h:80
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.
NUM_DERIVATIVES
The total number of derivatives supported.
double age() const
Returns the present age of the system in Gyr.
Definition: BinarySystem.h:833
unsigned number_locked_zones() const
How many zones on either body are currently locked.
Definition: BinarySystem.h:848
const DissipatingBody & secondary() const
Returns the secondary body in the system (const).
Definition: BinarySystem.h:839
std::list< double > __semimajor_rate_evolution
The rate at which the semimajor axis evolved at each.
Definition: BinarySystem.h:64
DissipatingBody & __body2
The second body in the system.
Definition: BinarySystem.h:174
BinarySystem(DissipatingBody &body1, DissipatingBody &body2, const std::string &system_name="")
Construct a binary system.
Definition: BinarySystem.h:763
std::list< unsigned > __locked_zones
A list of indices of locked zones.
Definition: BinarySystem.h:129
Core::EvolModeType __evolution_mode
The evolution mode from the last call to configure();.
Definition: BinarySystem.h:126
Eigen::ColPivHouseholderQR< Eigen::MatrixXd > __above_lock_fractions_decomp
The matrix that defines the problem to solve for __above_lock_fractions.
Definition: BinarySystem.h:166
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().
Definition: BinarySystem.h:996
NO_DERIV
The quantity itself, undifferentiated.
Eigen::Vector3d __orbit_torque_expansion_error
An estiamte of the error in ::__orbit_torque due to truncating the eccentricity series of the tidal p...
Definition: BinarySystem.h:119
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:852
const std::list< double > & semimajor_evolution_rate() const
The tabulated evolution of the semimajor axis so far.
virtual void change_e_order(unsigned new_e_order)
Change the eccentricity expansion order for all dissipative zones.
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:136
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:842
double semimajor_evolution_expansion_error() const
Estimate of the error in the value returned by semimajor_evolution() due to truncating the tidal pote...
Definition: BinarySystem.h:294
double eccentricity() const
The current eccentricity of the system.
Definition: BinarySystem.h:855
Describes a system of two bodies orbiting each other.
Definition: BinarySystem.h:56