Program Listing for File DissipatingZone.h¶
↰ Return to documentation for file (/home/kpenev/projects/git/poet/poet_src/Evolve/DissipatingZone.h)
#ifndef __DISSIPATING_ZONE_H
#define __DISSIPATING_ZONE_H
#include "ZoneOrientation.h"
#include "../Core/SharedLibraryExportMacros.h"
#include "../Core/Error.h"
#include "TidalPotentialTerms.h"
#include "DissipationQuantities.h"
#include "SpinOrbitLockInfo.h"
#include "CombinedStoppingCondition.h"
#include "BreakLockCondition.h"
#include "SynchronizedCondition.h"
#include "../Core/Common.h"
#include <valarray>
namespace Evolve {
enum ZoneEvolutionQuantities {
ANGULAR_MOMENTUM,
INCLINATION,
PERIAPSIS,
MOMENT_OF_INERTIA,
MOMENT_OF_INERTIA_FIRST_DERIV,
MOMENT_OF_INERTIA_SECOND_DERIV,
OUTER_RADIUS,
OUTER_RADIUS_FIRST_DERIV,
OUTER_RADIUS_SECOND_DERIV,
OUTER_MASS,
OUTER_MASS_DERIV,
NUM_REAL_EVOL_QUANTITIES,
E_ORDER=NUM_REAL_EVOL_QUANTITIES,
ORBITAL_FREQ_MULTIPLIER,
SPIN_FREQ_MULTIPLIER,
NUM_EVOL_QUANTITIES
}; //End ZoneEvolutionQuantities enumeration.
std::ostream &operator<<(std::ostream &os,
const ZoneEvolutionQuantities &evol_var);
class BinarySystem;
class TidalTermTriplet {
public:
double
m_minus_one,
m,
m_plus_one;
TidalTermTriplet(double m_minus_one_value = 0.0,
double m_value = 0.0,
double m_plus_one_value = 0.0):
m_minus_one(m_minus_one_value),
m(m_value),
m_plus_one(m_plus_one_value)
{}
TidalTermTriplet &operator=(const TidalTermTriplet &rhs)
{
m_minus_one = rhs.m_minus_one;
m = rhs.m;
m_plus_one = rhs.m_plus_one;
return *this;
}
};
class LIB_PUBLIC DissipatingZone : public ZoneOrientation {
private:
unsigned __e_order;
TidalPotentialTerms __potential_term;
static const double __torque_x_plus_coef[];
static const double __torque_x_minus_coef[];
double
__angular_momentum,
__spin_frequency,
__orbital_frequency,
__orbital_angmom;
std::valarray<double> __power,
__torque_x,
__torque_y,
__torque_z;
SpinOrbitLockInfo __lock,
__other_lock;
std::vector< std::list<double> > __evolution_real;
std::vector< std::list<int> > __evolution_integer;
unsigned __locked_zone_index;
bool __initializing;
void fix_forcing_frequency(
const SpinOrbitLockInfo &limit,
int orbital_frequency_multiplier,
int spin_frequency_multiplier,
double &forcing_frequency
) const;
void update_lock_to_lower_e_order(SpinOrbitLockInfo &lock);
void update_locks_to_higher_e_order(unsigned new_e_order);
void initialize_locks();
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,
const TidalTermTriplet &U_error
);
#ifndef NDEBUG
virtual void check_locks_consistency() const;
#endif
protected:
void initializing(bool flag) {__initializing = flag;}
void configure_spin(
double spin,
bool spin_is_frequency
);
public:
DissipatingZone();
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
);
double forcing_frequency(
int orbital_frequency_multiplier,
int spin_frequency_multiplier,
double orbital_frequency
) const;
void set_reference_zone_angmom(double reference_angmom)
{__orbital_angmom=reference_angmom;}
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()
);
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()
);
virtual bool locked(int orbital_frequency_multiplier,
int spin_frequency_multiplier) const
{return __lock(orbital_frequency_multiplier,
spin_frequency_multiplier);}
virtual bool locked() const
{return __lock;}
const SpinOrbitLockInfo &lock_held() const {return __lock;}
void release_lock();
void release_lock(
short direction
);
void set_lock(int orbital_frequency_multiplier,
int spin_frequency_multiplier)
{
assert(!__lock);
__lock.set_lock(orbital_frequency_multiplier,
spin_frequency_multiplier);
}
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;
virtual double love_coefficient(
int orbital_frequency_multiplier,
int spin_frequency_multiplier,
Dissipation::QuantityEntry entry
) const =0;
virtual double moment_of_inertia(
int deriv_order=0
) const =0;
virtual double moment_of_inertia(
double age,
int deriv_order=0
) const =0;
double spin_frequency() const {return __spin_frequency;}
double angular_momentum() const {return __angular_momentum;}
double tidal_power(
bool above,
Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
) const
{
if(entry == Dissipation::EXPANSION_ERROR)
entry = Dissipation::END_DIMENSIONLESS_DERIV;
assert(entry <= Dissipation::END_DIMENSIONLESS_DERIV);
assert(2 * entry + 1 < static_cast<int>(__power.size()));
return __power[2 * entry + (above? 1 : 0)];
}
double tidal_power(
double above_fraction,
Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
) const
{
if(entry == Dissipation::EXPANSION_ERROR)
entry = Dissipation::END_DIMENSIONLESS_DERIV;
assert(!locked() || (above_fraction >= 0 && above_fraction <= 1));
assert(entry <= Dissipation::END_DIMENSIONLESS_DERIV);
assert(2 * entry + 1 < static_cast<int>(__power.size()));
return (
above_fraction * __power[2 * entry + 1]
+
(1.0 - above_fraction) * __power[2 * entry]
);
}
double tidal_torque_x(
bool above,
Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
) const
{
if(entry == Dissipation::EXPANSION_ERROR)
entry = Dissipation::END_DIMENSIONLESS_DERIV;
assert(entry <= Dissipation::END_DIMENSIONLESS_DERIV);
assert(2 * entry + 1 < static_cast<int>(__torque_x.size()));
return __torque_x[2 * entry + (above ? 1 : 0)];
}
double tidal_torque_x(
double above_fraction,
Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
) const
{
if(entry == Dissipation::EXPANSION_ERROR)
entry = Dissipation::END_DIMENSIONLESS_DERIV;
assert(
!locked() || (above_fraction >= 0 && above_fraction <= 1)
);
assert(entry <= Dissipation::END_DIMENSIONLESS_DERIV);
assert(
2 * entry + 1
<
static_cast<int>(__torque_x.size())
);
return (above_fraction * __torque_x[2 * entry + 1]
+
(1.0 - above_fraction) * __torque_x[2 * entry]);
}
double tidal_torque_y(
bool above,
Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
) const
{
if(entry == Dissipation::EXPANSION_ERROR)
entry = Dissipation::END_DIMENSIONLESS_DERIV;
assert(entry <= Dissipation::END_DIMENSIONLESS_DERIV);
assert(
2 * entry + 1
<
static_cast<int>(__torque_y.size())
);
return __torque_y[2 * entry + (above? 1 : 0)];
}
double tidal_torque_y(
double above_fraction,
Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
) const
{
if(entry == Dissipation::EXPANSION_ERROR)
entry = Dissipation::END_DIMENSIONLESS_DERIV;
assert(!locked() || (above_fraction >= 0 && above_fraction <= 1));
assert(entry <= Dissipation::END_DIMENSIONLESS_DERIV);
assert(2 * entry + 1 < static_cast<int>(__torque_y.size()));
return (above_fraction * __torque_y[2 * entry + 1]
+
(1.0 - above_fraction) * __torque_y[2 * entry]);
}
double tidal_torque_z(
bool above,
Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
) const
{
if(entry == Dissipation::EXPANSION_ERROR)
entry = Dissipation::END_DIMENSIONLESS_DERIV;
assert(entry <= Dissipation::END_DIMENSIONLESS_DERIV);
assert(2 * entry + 1 < static_cast<int>(__torque_z.size()));
return __torque_z[2 * entry + (above? 1 : 0)];
}
double tidal_torque_z(
double above_fraction,
Dissipation::QuantityEntry entry=Dissipation::NO_DERIV
) const
{
if(entry == Dissipation::EXPANSION_ERROR)
entry = Dissipation::END_DIMENSIONLESS_DERIV;
assert(!locked() || (above_fraction >= 0 && above_fraction <= 1));
assert(entry < Dissipation::END_DIMENSIONLESS_DERIV);
assert(2 * entry + 1 < static_cast<int>(__torque_z.size()));
return (above_fraction * __torque_z[2 * entry + 1]
+
(1.0 - above_fraction) * __torque_z[2 * entry]);
}
//configure()).
virtual double outer_radius(
int deriv_order = 0
) const =0;
virtual double outer_radius(double age, int deriv_order=0) const =0;
virtual double outer_mass(
int deriv_order=0
) const =0;
virtual double outer_mass(double age, int deriv_order=0) const =0;
virtual unsigned eccentricity_order() const {return __e_order;}
virtual void change_e_order(
unsigned new_e_order,
BinarySystem &system,
bool primary,
unsigned zone_index
);
virtual void add_to_evolution();
virtual void rewind_evolution(
unsigned nsteps
);
virtual void reset_evolution();
const std::list<double> &get_evolution_real(
ZoneEvolutionQuantities quantity
) const
{
assert(quantity < NUM_REAL_EVOL_QUANTITIES);
return __evolution_real[quantity];
}
const std::list<int> &get_evolution_integer(
ZoneEvolutionQuantities quantity
) const
{
assert(quantity >= NUM_REAL_EVOL_QUANTITIES);
return __evolution_integer[quantity - NUM_REAL_EVOL_QUANTITIES];
}
unsigned locked_zone_index() const
{
assert(__lock);
return __locked_zone_index;
}
unsigned &locked_zone_index()
{
assert(__lock);
return __locked_zone_index;
}
virtual bool dissipative() const =0;
virtual CombinedStoppingCondition *stopping_conditions(
BinarySystem &system,
bool primary,
unsigned zone_index
);
virtual void spin_jumped()
{initialize_locks();}
virtual void reached_critical_age(double)
{assert(false);}
virtual double next_stop_age() const
{return Core::Inf;}
}; //End DissipatingZone class.
} //End Evolve namespace.
#endif