1 #define BUILDING_LIBRARY 8 double orbital_frequency)
10 double torque_norm = (
11 std::pow(companion_mass / std::pow(semimajor, 3), 2)
25 double dangular_velocity_da = -1.5 * orbital_frequency / semimajor;
26 for(
unsigned zone_index = 0; zone_index <
number_zones(); ++zone_index) {
85 no_deriv_ind = invalid_ind,
86 orbital_freq_deriv_ind = invalid_ind,
87 radius_deriv_ind = invalid_ind,
88 semimajor_deriv_ind = invalid_ind;
100 unsigned zone_index = 0;
109 unsigned deriv_ind = 0;
144 tidal_torque[Dissipation::NO_DERIV],
168 unsigned correction_index = 0;
169 for(
unsigned zone_index=0; zone_index<
number_zones(); ++zone_index)
190 Eigen::Vector3d &outer_angmom_gain,
191 Eigen::Vector3d &inner_angmom_gain,
192 Dissipation::QuantityEntry deriv,
193 bool with_respect_to_outer
203 lost_spin = (dm_dt >= 0
214 outer_angmom_gain[0] = outer_angmom_gain[1] = 0;
221 Eigen::Vector3d(0, 0, angmom_transfer),
223 with_respect_to_outer
226 inner_angmom_gain[0] = inner_angmom_gain[1] = 0;
233 Eigen::Vector3d(0, 0, angmom_transfer),
235 !with_respect_to_outer
242 Dissipation::QuantityEntry deriv,
243 bool with_respect_to_outer
246 assert(zone_index > 0);
249 &zone_above =
zone(zone_index - 1);
250 double scaling = Core::NaN,
268 (with_respect_to_outer && dm_dt <= 0)
270 (!with_respect_to_outer && dm_dt>=0)
272 return Eigen::Vector3d(0, 0, 0);
274 scaling = 1.0 / (with_respect_to_outer
275 ? zone_above.spin_frequency()
278 scaling = -1.0 / (with_respect_to_outer
279 ? zone_above.moment_of_inertia()
281 else scaling = 1.0 / (with_respect_to_outer
282 ? zone_above.angular_momentum()
290 return Eigen::Vector3d(0, 0, 0);
292 Eigen::Vector3d dummy, result;
298 with_respect_to_outer);
308 Dissipation::QuantityEntry deriv,
309 bool with_respect_to_inner
315 &zone_below =
zone(zone_index + 1);
316 double scaling = Core::NaN,
317 dm_dt = zone_below.outer_mass(1);
322 2.0 * zone_below.outer_radius(1) / zone_below.outer_radius(0)
324 zone_below.outer_mass(2) / dm_dt
334 (with_respect_to_inner && dm_dt >= 0)
336 (!with_respect_to_inner && dm_dt <= 0)
338 return Eigen::Vector3d(0, 0, 0);
340 scaling = 1.0 / (with_respect_to_inner
341 ? zone_below.spin_frequency()
344 scaling = -1.0 / (with_respect_to_inner
345 ? zone_below.moment_of_inertia()
347 else scaling = 1.0 / (with_respect_to_inner
348 ? zone_below.angular_momentum()
356 return Eigen::Vector3d(0, 0, 0);
358 Eigen::Vector3d dummy, result;
364 !with_respect_to_inner);
374 Dissipation::QuantityEntry deriv,
389 return Eigen::Vector3d(0,0,0);
390 Eigen::Vector3d result(0, 0, 0);
439 Eigen::VectorXd &above_lock_fractions_age_deriv,
440 Eigen::VectorXd &above_lock_fractions_semimajor_deriv,
441 Eigen::VectorXd &above_lock_fractions_eccentricity_deriv,
442 Eigen::VectorXd &above_lock_fractions_radius_deriv
445 unsigned correction_index = 0;
447 unsigned zone_index = 0;
452 unsigned locked_zone_index = (
461 unsigned entry_ind = 0;
465 Dissipation::QuantityEntry entry = (
484 double frac_deriv = Core::NaN;
486 frac_deriv = (above_lock_fractions_age_deriv
487 [locked_zone_index]);
490 above_lock_fractions_semimajor_deriv
497 above_lock_fractions_eccentricity_deriv
503 frac_deriv = (above_lock_fractions_radius_deriv
504 [locked_zone_index]);
506 frac_deriv = (above_lock_fractions_semimajor_deriv
507 [locked_zone_index]);
524 std::valarray<Eigen::VectorXd> &above_lock_fractions
528 unsigned correction_index = 0;
530 unsigned zone_index = 0;
535 unsigned locked_zone_index = (
541 entry_int < Dissipation::NUM_ENTRIES;
544 Dissipation::QuantityEntry entry = (
545 static_cast<Dissipation::QuantityEntry
>(entry_int)
547 Eigen::Vector3d correction = (
583 static_cast<Dissipation::QuantityEntry>(
592 above_lock_fractions[entry][locked_zone_index]
605 double companion_mass,
608 const double *spin_angmom,
609 const double *inclination,
610 const double *periapsis,
612 bool zero_outer_inclination,
613 bool zero_outer_periapsis)
615 double orbital_angmom=Core::orbital_angular_momentum(
637 std::cerr <<
"Initializing DissipatingBody" << std::endl;
644 unsigned angmom_offset = (locked_surface ? 1 : 0);
646 unsigned zone_index = 0;
651 double zone_inclination, zone_periapsis, zone_spin;
653 zone_inclination = 0;
654 else if(zero_outer_inclination)
655 zone_inclination = (zone_index
656 ? inclination[zone_index - 1]
659 zone_inclination = inclination[zone_index];
662 else if(zero_outer_periapsis)
663 zone_periapsis = (zone_index ? periapsis[zone_index-1] : 0);
665 zone_periapsis = periapsis[zone_index];
666 if(locked_surface && zone_index == 0)
668 else if(current_zone.
locked() && !initialize) {
669 zone_spin = Core::NaN;
672 zone_spin = spin_angmom[zone_index - angmom_offset];
674 std::cerr <<
"Configuring zone " << zone_index << std::endl;
684 locked_surface && zone_index == 0);
687 unsigned zone_index = 0;
696 zone(zone_index + 1),
706 tidal_torque.resize(Dissipation::NUM_ENTRIES);
712 Dissipation::QuantityEntry entry = (
714 ?
static_cast<Dissipation::QuantityEntry
>(torque_ind)
729 assert(!std::isnan(tidal_torque[entry].sum()));
744 Dissipation::QuantityEntry deriv,
750 assert(static_cast<int>(zone_index) + deriv_zone >= 0);
751 assert(static_cast<int>(zone_index) + deriv_zone
755 Eigen::Vector3d result(0, 0, 0);
756 if(zone_index == 0 && deriv_zone == 0)
764 (!zone_specific(deriv) || deriv_zone >= 0)
772 (!zone_specific(deriv) || deriv_zone<=0)
787 zone(zone_index - 1),
799 Dissipation::QuantityEntry entry)
const 828 std::valarray<Eigen::VectorXd> &above_lock_fractions
850 Dissipation::QuantityEntry entry,
851 unsigned deriv_zone_index,
852 const Eigen::VectorXd &above_lock_fraction_deriv
856 double result = Core::NaN;
858 !zone_specific(entry)
864 if(zone_specific(entry)) {
865 result =
tidal_power(deriv_zone_index,
false, entry);
888 assert(above_lock_fraction_deriv.size()
892 unsigned correction_index = 0;
893 for(
unsigned zone_index = 0; zone_index <
number_zones(); ++zone_index)
896 above_lock_fraction_deriv
907 Dissipation::QuantityEntry entry,
908 unsigned deriv_zone_index,
909 const Eigen::VectorXd &above_lock_fraction_deriv
912 if(zone_specific(entry) && deriv_zone_index != 0) {
931 assert(above_lock_fraction_deriv.size()
935 unsigned correction_index = 0;
937 unsigned zone_index = 0;
943 above_lock_fraction_deriv[
973 [Dissipation::NO_DERIV]
987 Dissipation::QuantityEntry entry,
988 unsigned deriv_zone_index,
989 const Eigen::VectorXd &above_lock_fraction_deriv
992 Eigen::Vector3d result;
1003 above_lock_fraction_deriv)
1013 deriv_zone_index == 0
1015 &
zone(deriv_zone_index) == &reference_zone
1022 deriv_zone_index==0);
1030 for(
unsigned zone_ind = 0; zone_ind <
number_zones(); ++zone_ind)
1036 for(
unsigned zone_ind = 0; zone_ind <
number_zones(); ++zone_ind)
1042 for(
unsigned zone_ind = 0; zone_ind <
number_zones(); ++zone_ind)
1052 for(
unsigned zone_ind = 0; zone_ind <
number_zones(); ++zone_ind)
1063 for(
unsigned zone_ind = 0; zone_ind <
number_zones(); ++zone_ind)
double __power_norm
The coefficient used to normalize tidal power.
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).
std::valarray< std::valarray< Eigen::Vector3d > > __angular_momentum_transfer
The rate of angular momentum transfer between two neighboring zones due to zone boundaries moving...
virtual void rewind_evolution(unsigned nsteps)
Discards the last steps from the evolution.
virtual void reset_evolution()
Discards all evolution.
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.
virtual void add_to_evolution()
Appends the state defined by last configure(), to the evolution.
double angular_momentum() const
The angular momentum of the given zone in .
void set_above_lock_fractions(std::valarray< Eigen::VectorXd > &above_lock_fractions)
Corrects the tidal orbit energy gain and angular momentum gain for locked zones.
Eigen::Vector3d angular_momentum_transfer_from_bottom(unsigned zone_index, Dissipation::QuantityEntry deriv=Dissipation::NO_DERIV, bool with_respect_to_inner=false) const
Rate of angular momentum transfer (or its derivatives) to a zone due to its bottom boundary moving...
SPIN_FREQUENCY
The derivative w.r.t. the spin frequency of a dissipating zone.
DissipatingBody()
Some initializations for new objects.
double tidal_power(unsigned zone_index, bool above, Dissipation::QuantityEntry entry=Dissipation::NO_DERIV) const
Tidal power dissipated in the given zone.
Eigen::Vector3d angular_momentum_transfer_from_top(unsigned zone_index, Dissipation::QuantityEntry deriv=Dissipation::NO_DERIV, bool with_respect_to_outer=false) const
Rate of angular momentum transfer (or its derivatives) to a zone due to its top boundary moving...
virtual Eigen::Vector3d angular_momentum_coupling(unsigned top_zone_index, Dissipation::QuantityEntry deriv=Dissipation::NO_DERIV, bool with_respect_to_top=false) const =0
Coupling torque for two neighboring zones in the coordinate system of the top zone.
virtual void add_to_evolution()
Appends the state defined by last configure(), to the evolution.
virtual const DissipatingZone & zone(unsigned zone_index) const =0
A modifiable reference to one of the body's zones.
SEMIMAJOR
The derivative w.r.t. the semimajor axis in AU.
Eigen::Vector3d zone_to_zone_transform(const ZoneOrientation &from_zone, const ZoneOrientation &to_zone, const Eigen::Vector3d &vector, Dissipation::QuantityEntry deriv, bool with_respect_to_from)
Transforms a vector betwen the coordinates systems of two zones.
double surface_lock_frequency() const
Angular velocity of the surface zone when locked (assumed constant).
Orientations of zones of bodies in a binary system.
double tidal_torque_y(bool above, Dissipation::QuantityEntry entry=Dissipation::NO_DERIV) const
The dimensionless torque along y.
NUM_DERIVATIVES
The total number of derivatives supported.
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...
double mass() const
The mass of the body (constant with age).
void calculate_orbit_rate_corrections()
Calculates the correction the orbital energy gain and torque due to switching locked zones from fully...
virtual void configure(bool initialize, double age, double companion_mass, double semimajor, double eccentricity, const double *spin_angmom, const double *inclination=NULL, const double *periapsis=NULL, bool locked_surface=false, bool zero_outer_inclination=false, bool zero_outer_periapsis=false)
Defines the orbit this body is in.
virtual CombinedStoppingCondition * stopping_conditions(BinarySystem &system, bool primary)
Conditions detecting the next possible discontinuities in the evolution due to this body...
double __dorbital_frequency_da
The derivative of the orbital frequency w.r.t. semimajor axis.
double radius(int deriv_order=0) const
The current radius or its derivative with age of the body.
Eigen::Vector3d nontidal_torque(unsigned zone_index, Dissipation::QuantityEntry deriv=Dissipation::NO_DERIV, int deriv_zone=0) const
External torque acting on a single zone (last calculate_torques_power()).
const double solar_radius
Radius of the sun [m].
A layer of a system body for which the tidal bulge is not exactly in phase with the tidal potential...
virtual void reset_evolution()
Discards all evolution.
double __orbital_frequency
The mean angular velocity with which the orbit is traversed.
double normalize_torques(double companion_mass, double semimajor, double orbital_frequency)
Scales the dimensionless torques as appropriate and corrects the relevant derivatives returning the n...
std::valarray< std::valarray< Eigen::Vector3d > > __tidal_torques_below
Tidal torques and their derivatives on each zone for spin frequency approaching potential lock from b...
virtual double outer_mass(int deriv_order=0) const =0
Mass coordinate of the zone's outer ouboundary or its derivative.
void correct_orbit_torque(std::valarray< Eigen::VectorXd > &above_lock_fractions)
Corrects __orbit_torque for zone locks.
ECCENTRICITY
The derivative w.r.t. the eccentricity.
virtual void change_e_order(unsigned new_e_order, BinarySystem &system, bool primary)
Change the eccentricity expansion order for all dissipative zones.
const double solar_mass
Mass of the sun [kg].
AGE
The derivative w.r.t. age, excluding the dependence through the body's radius and the moments of iner...
std::vector< Eigen::Vector3d > __orbit_torque_correction
Corrections to __orbit_torque_below (undifferentiated) if single zones switch to above.
virtual double angular_momentum_loss(Dissipation::QuantityEntry deriv=Dissipation::NO_DERIV) const =0
Rate of angular momentum loss by the top zone of the body and its derivatives.
void angular_momentum_transfer(const DissipatingZone &outer_zone, const DissipatingZone &inner_zone, Eigen::Vector3d &outer_angmom_gain, Eigen::Vector3d &inner_angmom_gain, Dissipation::QuantityEntry deriv=Dissipation::NO_DERIV, bool with_respect_to_outer=false) const
Angular momentum transfer between two neighboring zones due to moving zone boundaries.
virtual CombinedStoppingCondition * stopping_conditions(BinarySystem &system, bool primary, unsigned zone_index)
Conditions detecting the next possible discontinuities in the evolution due to this zone...
virtual bool locked(int orbital_frequency_multiplier, int spin_frequency_multiplier) const
Should return true iff the given term is presently locked.
NO_DERIV
The quantity itself, undifferentiated.
Declares the DissipatingBody class.
ORBITAL_FREQUENCY
The derivative w.r.t. the orbital frequency.
double tidal_torque_z(bool above, Dissipation::QuantityEntry entry=Dissipation::NO_DERIV) const
The dimensionless tidal torque along z.
std::vector< Dissipation::QuantityEntry > __orbit_entries
The quantities w.r.t. which derivatives of the orbit energy gain and torque are pre-calculated or err...
SPIN_ANGMOM
The derivative w.r.t. the spin angular momentum in .
double tidal_orbit_power(Dissipation::QuantityEntry entry=Dissipation::NO_DERIV, unsigned deriv_zone_index=0, const Eigen::VectorXd &above_lock_fraction_deriv=Eigen::VectorXd()) const
Rate of increase of the orbital energy due to tides in this body (last calculate_torques_power()).
virtual void rewind_evolution(unsigned nsteps)
Discards the last steps from the evolution.
const Eigen::Vector3d & tidal_torque(unsigned zone_index, bool above, Dissipation::QuantityEntry entry=Dissipation::NO_DERIV) const
Tidal torque acting on the given zone (last calculate_torques_power()).
Eigen::Vector3d angular_momentum_transfer_to_zone(unsigned zone_index, Dissipation::QuantityEntry deriv=Dissipation::NO_DERIV, int deriv_zone=0) const
Rate of angular momentum transfer (or its derivatives) to a zone due to moving zone boundaries...
void collect_orbit_rates(double orbital_frequency, double torque_norm)
Calcuates the total energy and angular momentum loss rates for the orbit due to this body's tidal dis...
std::valarray< std::valarray< Eigen::Vector3d > > __tidal_torques_above
Tidal torques and their derivatives on each zone for spin frequency approaching potential lock from a...
virtual void change_e_order(unsigned new_e_order, BinarySystem &system, bool primary, unsigned zone_index)
Changes the order of the eccentricity expansion performed.
A class combining the the outputs of multiple stopping conditions.
void correct_orbit_power(Eigen::VectorXd &above_lock_fractions_age_deriv, Eigen::VectorXd &above_lock_fractions_semimajor_deriv, Eigen::VectorXd &above_lock_fractions_eccentricity_deriv, Eigen::VectorXd &above_lock_fractions_radius_deriv)
Corrects __orbit_power for zone locks.
std::vector< Eigen::Vector3d > __orbit_torque
Torque on the orbit (and its derivatives and error) due to tides on this body.
virtual bool dissipative() const =0
Should return true iff the zone has some non-zero dissipation.
std::valarray< Eigen::VectorXd > __above_lock_fractions
The fractional contribution of the above the lock rates for locked zones and their derivatives...
unsigned __num_locked_zones
The number of zones currently in a spin-orbit lock.
double tidal_torque_x(bool above, Dissipation::QuantityEntry entry=Dissipation::NO_DERIV) const
The dimensionless tidal torque along x.
Describes a system of two bodies orbiting each other.
std::valarray< double > __orbit_power
Total tidal power (and derivatives and error) gained by the orbit from this body. ...
std::valarray< double > __orbit_power_correction
Corrections to __orbit_power_below (undifferentiated) if single zones switch to above.
Eigen::Vector3d tidal_orbit_torque(Dissipation::QuantityEntry deriv=Dissipation::NO_DERIV, unsigned deriv_zone_index=0, const Eigen::VectorXd &above_lock_fraction_deriv=Eigen::VectorXd()) const
The torque on the orbit due to tidal dissipation in the body.
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 surface spin freuqency of the body.
double spin_frequency() const
The spin frequency of the given zone.
const double G
Gravitational constant in SI.
virtual unsigned number_zones() const =0
The number of zones the body consists of.