1 #define BUILDING_LIBRARY 15 case PERIAPSIS : os <<
"PERIAPSIS";
break;
19 os <<
"DMOMENT_OF_INERTIA_DT";
break;
21 os <<
"D2MOMENT_OF_INERTIA_DT2";
break;
27 case E_ORDER : os <<
"E_ORDER";
break;
31 default : assert(
false);
50 int orbital_frequency_multiplier,
51 int spin_frequency_multiplier,
52 double &forcing_frequency
61 limit.
term(orbital_frequency_multiplier,
62 spin_frequency_multiplier)
65 spin_frequency_multiplier
80 std::numeric_limits<double>::epsilon()
84 int expected_sign = boost::math::sign(
88 orbital_frequency_multiplier
94 spin_frequency_multiplier
102 if(forcing_frequency * expected_sign > 0)
return;
106 forcing_frequency = (
107 std::numeric_limits<double>::epsilon()
116 std::cerr <<
"Checking lock consistency for __lock: " 118 <<
", __other_lock: " 133 "Inconsistent lock state encountered for a zone. Likely related " 134 "to initial conditions with a tidal term too close to zero." 248 int below_orb_mult = std::floor(2.0
254 if(below_orb_mult % 2) {
256 std::abs(below_orb_mult)
263 std::abs((below_orb_mult - 1) / 2)
268 if((below_orb_mult + 1) / 2 > max_abs_orb_mult)
281 }
else if(std::abs(below_orb_mult / 2) <= max_abs_orb_mult) {
283 if(std::abs(below_orb_mult + 1) <= max_abs_orb_mult)
285 else if(std::abs(below_orb_mult / 2 + 1) <= max_abs_orb_mult)
304 double tidal_frequency,
311 bool locked_term =
locked(mp, m);
322 Dissipation::QuantityEntry phase_lag_deriv = (
324 ?
static_cast<Dissipation::QuantityEntry
>(deriv)
327 double mod_phase_lag_above,
353 double U_mmp_squared = std::pow(U.
m, 2),
354 term_power = U_mmp_squared * mp,
355 term_torque_z = U_mmp_squared * m,
356 term_torque_x = U.
m * (
366 mod_phase_lag_above = mod_phase_lag_below;
374 mod_phase_lag_below = mod_phase_lag_above;
375 int deriv_ind = 2 * deriv;
376 __power[deriv_ind] += term_power * mod_phase_lag_below;
379 mod_phase_lag_below);
382 mod_phase_lag_below);
384 __torque_y[deriv_ind] -= term_torque_x * love_coef
386 __power[deriv_ind + 1] += term_power * mod_phase_lag_above;
389 mod_phase_lag_above);
392 mod_phase_lag_above);
396 assert(!std::isnan(
__torque_x[deriv_ind + 1]));
398 assert(!std::isnan(
__torque_y[deriv_ind + 1]));
400 assert(!std::isnan(
__torque_z[deriv_ind + 1]));
403 if(deriv == Dissipation::NO_DERIV)
404 std::cerr <<
", Wzone = " 406 <<
", U(" << m <<
", " << mp <<
") = " 410 <<
", mod_phase_lag(above=" 411 << mod_phase_lag_above
413 << mod_phase_lag_below
420 bool spin_is_frequency)
422 if(spin_is_frequency) {
432 DissipatingZone::DissipatingZone() :
449 double orbital_frequency,
451 double orbital_angmom,
455 bool spin_is_frequency)
462 std::cerr <<
"Initializing DissipatingZone" << std::endl;
466 std::cerr <<
"At t = " << age <<
", configuring " 468 <<
"dissipative zone with w = " 472 <<
", inclination = " << inclination
473 <<
", periapsis = " << periapsis
480 if(
__lock && !initialize) {
490 if(std::isnan(orbital_frequency))
return;
515 for(
int m = -2; m <= 2; ++m) {
517 std::cerr <<
"Term: m' = " 552 std::cerr << std::endl;
559 int orbital_frequency_multiplier,
560 int spin_frequency_multiplier,
561 double orbital_frequency
571 if(
__lock(orbital_frequency_multiplier, spin_frequency_multiplier))
573 double forcing_freq = (
574 orbital_frequency_multiplier * orbital_frequency
578 assert(!std::isnan(forcing_freq));
593 orbital_frequency_multiplier,
594 spin_frequency_multiplier,
598 orbital_frequency_multiplier,
599 spin_frequency_multiplier,
610 const Eigen::Vector3d &orbit_torque,
611 const Eigen::Vector3d &zone_torque,
612 Dissipation::QuantityEntry entry,
613 const Eigen::Vector3d &orbit_torque_deriv,
614 const Eigen::Vector3d &zone_torque_deriv
622 orbit_y_torque = orbit_torque[1];
623 zone_y_torque = zone_torque[1];
625 orbit_y_torque = orbit_torque_deriv[1];
626 zone_y_torque = zone_torque_deriv[1];
630 assert(orbit_y_torque == 0 || std::isnan(orbit_y_torque));
631 assert(zone_y_torque == 0 || std::isnan(zone_y_torque));
633 assert(!std::isnan(orbit_y_torque));
634 assert(!std::isnan(zone_y_torque));
646 assert(!std::isnan(result));
669 if(sin_inc == 0)
return 0.0;
680 if(sin_inc == 0)
return 0.0;
700 const Eigen::Vector3d &orbit_torque,
701 const Eigen::Vector3d &zone_torque,
702 Dissipation::QuantityEntry entry,
703 const Eigen::Vector3d &orbit_torque_deriv,
704 const Eigen::Vector3d &zone_torque_deriv)
711 assert(!std::isnan(orbit_torque[0]));
712 assert(!std::isnan(orbit_torque[2]));
713 assert(!std::isnan(zone_torque[0]));
715 orbit_x_torque = orbit_torque[0];
716 orbit_z_torque = orbit_torque[2];
717 zone_x_torque = zone_torque[0];
719 orbit_x_torque = orbit_torque_deriv[0];
720 orbit_z_torque = orbit_torque_deriv[2];
721 zone_x_torque = zone_torque_deriv[0];
725 if(orbit_x_torque == 0 && orbit_z_torque == 0)
728 result = ((orbit_x_torque * cos_inc - orbit_z_torque * sin_inc)
735 assert(!std::isnan(result));
770 (orbit_torque[2] * cos_inc + orbit_torque[0] * sin_inc)
806 assert(direction == 1 || direction == -1);
826 unsigned new_expansion_order,
834 std::cerr <<
"Changing eccentricity order to " 835 << new_expansion_order
841 std::cerr <<
"No lock defined, simple e-order change." << std::endl;
846 std::cerr <<
"Lock(s) defined, updating." << std::endl;
926 for(
unsigned i = 0; i < nsteps; ++i) {
ZoneEvolutionQuantities
IDs for quantities saved as part of the evolution.
double m
The (m, m') coefficient.
Age derivative of MOMENT_OF_INERTIA.
unsigned __locked_zone_index
If this zone is locked, this is its index in the list of locked zones in the system.
RADIUS
The derivative w.r.t. the radius of the body in .
virtual void configure(bool initialize, double age, double orbital_frequency, double eccentricity, double orbital_angmom, double spin, double inclination, double periapsis, bool spin_is_frequency)
Defines the current orbit, triggering re-calculation of all quantities.
END_PHASE_LAG_DERIV
The above derivatives exist for modified phase lags, below do not.
The rate at which periapsis changes.
Satisfied when some multiples of the orbit and stellar rotation are synchronized. ...
std::valarray< double > __power
The dimensionless tidal power and its derivatives.
Declares a class representing one zone of a body dissipative to tidal distortions.
The total number of quantities whose evolution is tracked.
SPIN_FREQUENCY
The derivative w.r.t. the spin frequency of a dissipating zone.
void add_tidal_term(int m, int mp, double tidal_frequency, const TidalTermTriplet &U_value, const TidalTermTriplet &U_i_deriv, const TidalTermTriplet &U_e_deriv)
Add a term to the tidal torque and power arrays.
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.
int orbital_frequency_multiplier() const
The multiplier in front of the orbital frequency in the lock.
virtual void add_to_evolution()
Appends the state defined by last configure(), to the evolution.
unsigned __expansion_order
The tidal potential expansion order to use.
double periapsis(bool evolution_rate=false) const
The argument of periapsis of this zone minus the reference zone's.
Satisfied when the maximum tidal torque that the planet can exert on the star is no longer sufficient...
The rate at which the the inclination changes.
SEMIMAJOR
The derivative w.r.t. the semimajor axis in AU.
static const double __torque_x_plus_coef[]
as a function of .
std::vector< std::list< double > > __evolution_real
The floating point quantities whose evolution is tracked.
Outer radius boundary of the zone.
virtual double modified_phase_lag(int orbital_frequency_multiplier, int spin_frequency_multiplier, double forcing_frequency, Dissipation::QuantityEntry entry, double &above_lock_value) const =0
Should return the tidal phase lag times the love number for the given tidal term (or one of its deriv...
virtual double love_coefficient(int orbital_frequency_multiplier, int spin_frequency_multiplier, Dissipation::QuantityEntry entry) const =0
Should return the corresponding component of the love coefficient (Lai 2012 Equation 24)...
Orientations of zones of bodies in a binary system.
double spin(double orbital_frequency) const
Spin frequency at exactly the lock that corresponds to the given orbital frequency.
Number of real values evolution quantities.
Eccentricity expansion order.
void release_lock()
Update the zone as necessary when the held lock disappears from the expansion.
First age derivative of OUTER_MASS.
virtual double moment_of_inertia(int deriv_order=0) const =0
Moment of inertia of the zone or its age derivative at the age of last configure() call...
std::valarray< double > __torque_x
The dimensionless tidal torque in the x direction and its derivatives.
double __angular_momentum_evolution_rate
The current rate of angular momentum evolution of the zone.
double m_minus_one
The (m-1, m') coefficient.
int spin_frequency_multiplier() const
The multiplier in front of the spin frequency in the lock.
void configure(double inclination, double arg_of_periapsis=0)
Set the inclination relative to the orbit.
virtual void reset_evolution()
Discards all evolution.
double __orbital_frequency
The orbital frequency (rad/day).
short lock_direction() const
double m_plus_one
The (m+1, m') coefficient.
void configure(double inclination, double periapsis)
Changes the zone orientation.
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...
double __angular_momentum
The current angular momentum of the zone.
virtual double outer_mass(int deriv_order=0) const =0
Mass coordinate of the zone's outer ouboundary or its derivative.
double periapsis_evolution(const Eigen::Vector3d &orbit_torque, const Eigen::Vector3d &zone_torque, Dissipation::QuantityEntry entry=Dissipation::NO_DERIV, const Eigen::Vector3d &orbit_torque_deriv=Eigen::Vector3d(), const Eigen::Vector3d &zone_torque_deriv=Eigen::Vector3d())
The rate at which the periapsis of the orbit/reference zone in this zone's equatorial plane is changi...
ECCENTRICITY
The derivative w.r.t. the eccentricity.
For locked zones this is the orbital frequency multiple of the lock.
void fix_forcing_frequency(const SpinOrbitLockInfo &limit, int orbital_frequency_multiplier, int spin_frequency_multiplier, double &forcing_frequency) const
Ensure the forcing frequency has the correct sign per the given constraint.
Moment of inertia of the zone.
virtual void change_expansion_order(unsigned new_expansion_order, BinarySystem &system, bool primary, unsigned zone_index)
Changes the order of the eccentricity expansion performed.
AGE
The derivative w.r.t. age, excluding the dependence through the body's radius and the moments of iner...
Defines the BinarySystem class.
Core::EvolModeType evolution_mode()
The evolution mode of last call to configure().
virtual CombinedStoppingCondition * stopping_conditions(BinarySystem &system, bool primary, unsigned zone_index)
Conditions detecting the next possible discontinuities in the evolution due to this zone...
double inclination(bool evolution_rate=false) const
The angle between the angular momenta of the zone and the orbit.
Outer mass boundary of the zone.
NO_DERIV
The quantity itself, undifferentiated.
SpinOrbitLockInfo __lock
The lock the zone is currently held at (disabled if not locked).
Second age deriv of OUTER_RADIUS.
std::vector< std::list< int > > __evolution_integer
The integer quantities whose evolution is tracked.
bool term(int orbital_freq_mult, int spin_freq_mult) const
Angular momentum of the zone.
SPIN_ANGMOM
The derivative w.r.t. the spin angular momentum in .
double inclination_evolution(const Eigen::Vector3d &orbit_torque, const Eigen::Vector3d &zone_torque, Dissipation::QuantityEntry entry=Dissipation::NO_DERIV, const Eigen::Vector3d &orbit_torque_deriv=Eigen::Vector3d(), const Eigen::Vector3d &zone_torque_deriv=Eigen::Vector3d())
The rate at which the inclination between this zone and the orbit is changing.
static const double __torque_x_minus_coef[]
as a function of .
virtual void rewind_evolution(unsigned nsteps)
Discards the last steps from the evolution.
First age deriv of OUTER_RADIUS.
void configure_spin(double spin, bool spin_is_frequency)
Configures only the spin of the zone.
void update_lock_to_lower_expansion_order(SpinOrbitLockInfo &lock)
Updates a SpinOrbitLockInfo variable as appropriate when decreasing the eccentricity expansion order...
Age second deriv of MOMENT_OF_INERTIA.
std::valarray< double > __torque_y
The dimensionless tidal torque in the y direction and its derivatives.
double forcing_frequency(int orbital_frequency_multiplier, int spin_frequency_multiplier, double orbital_frequency) const
The tidal forcing frequency for the given term and orbital frequency.
std::valarray< double > __torque_z
The dimensionless tidal torque in the z direction and its derivatives.
The rate at which angular momentum changes.
A class combining the the outputs of multiple stopping conditions.
void select_locks_to_monitor()
Initializes the locks the first time the zone is configure() -ed.
virtual bool dissipative() const =0
Should return true iff the zone has some non-zero dissipation.
bool __initializing
Is the zone in the middle of initializing (disable lock check)?
virtual bool can_lock() const =0
Should return true iff the zone's dissipation is discontinuous at zero frequency. ...
For locked zones this is the spin frequency multiple of the lock.
double __orbital_angmom
The absolute value of the angular momentum of the orbit.
virtual bool locked() const
Should return true iff any tidal term is locked.
Describes a system of two bodies orbiting each other.
void set_lock(int orbital_freq_mult, int spin_freq_mult, short lock_direction=0)
Define which tidal dissipation term is in a lock.
virtual double outer_radius(int deriv_order=0) const =0
Outer radius of the zone or its derivative (per last.
double spin_frequency() const
The spin frequency of the given zone.
virtual void check_locks_consistency() const
Runs a bunch of asserts to check the consistency of __lock and __other_lock.
Defines a lock between the spin of a dissipating body and the orbit.