Program Listing for File LagSpinBreakCondition.cpp¶
↰ Return to documentation for file (/home/kpenev/projects/git/poet/poet_src/Evolve/LagSpinBreakCondition.cpp)
#define BUILDING_LIBRARY
#include "LagSpinBreakCondition.h"
#include "BrokenPowerlawPhaseLagZone.h"
namespace Evolve {
void LagSpinBreakCondition::set_num_subconditions()
{
if(
__powerlaw_index == 0
||
__powerlaw_index == __zone.__spin_frequency_breaks.size()
)
__num_subconditions = 1;
else
__num_subconditions = 2;
}
double LagSpinBreakCondition::derivative(double surf_angmom_deriv,
double wcritical) const
{
return (
(
(__zone.spin_frequency() < 0 ? -1.0 : 1.0)
*
surf_angmom_deriv
-
__zone.moment_of_inertia(1)
*
__zone.spin_frequency()
)
/
(__zone.moment_of_inertia() * wcritical)
);
}
void LagSpinBreakCondition::fill_locked_derivs(
Core::EvolModeType
#ifndef NDEBUG
evol_mode
#endif
,
const std::valarray<double> &orbit,
const std::valarray<double> &derivatives,
std::valarray<double> &stop_deriv
) const
{
assert(evol_mode == Core::BINARY);
double deriv_factor = (-1.5 * __zone.spin_frequency()
*
derivatives[0] / orbit[0]);
unsigned subcond = 0;
if(__powerlaw_index > 0)
stop_deriv[subcond++] = (
deriv_factor
/
__zone.__spin_frequency_breaks[__powerlaw_index - 1]
);
if(__powerlaw_index < __zone.__spin_frequency_breaks.size())
stop_deriv[subcond] = (
deriv_factor
/
__zone.__spin_frequency_breaks[__powerlaw_index]
);
}
void LagSpinBreakCondition::fill_unlocked_derivs(
Core::EvolModeType evol_mode,
const std::valarray<double> &,
const std::valarray<double> &derivatives,
std::valarray<double> &stop_deriv
) const
{
unsigned angmom_index = 1 + __zone_index + 2 * __body.number_zones();
if(evol_mode == Core::BINARY)
angmom_index += (
2 * __other_body.number_zones()
+
(__primary
? 0
: (__other_body.number_zones()
-
__other_body.number_locked_zones()))
);
else angmom_index -= 3;
assert(angmom_index <= derivatives.size());
double surf_angmom_deriv = derivatives[angmom_index];
if(__powerlaw_index > 0)
stop_deriv[0] = derivative(
surf_angmom_deriv,
__zone.__spin_frequency_breaks[__powerlaw_index - 1]
);
if(__powerlaw_index < __zone.__spin_frequency_breaks.size())
stop_deriv[1] = derivative(
surf_angmom_deriv,
__zone.__spin_frequency_breaks[__powerlaw_index]
);
}
LagSpinBreakCondition::LagSpinBreakCondition(
BrokenPowerlawPhaseLagZone &zone,
const DissipatingBody &body,
const DissipatingBody &other_body,
bool primary,
unsigned zone_index
) :
__zone(zone),
__body(body),
__other_body(other_body),
__primary(primary),
__zone_index(zone_index),
__powerlaw_index(__zone.__spin_index)
{
set_num_subconditions();
}
std::valarray<double> LagSpinBreakCondition::operator()(
Core::EvolModeType evol_mode,
const std::valarray<double> &orbit,
const std::valarray<double> &derivatives,
std::valarray<double> &stop_deriv
) const
{
assert(evol_mode != Core::LOCKED_SURFACE_SPIN);
assert(__primary || evol_mode == Core::BINARY);
stop_deriv.resize(__num_subconditions, Core::NaN);
if(__zone.locked())
fill_locked_derivs(evol_mode, orbit, derivatives, stop_deriv);
else
fill_unlocked_derivs(evol_mode, orbit, derivatives, stop_deriv);
std::valarray<double> result(__num_subconditions);
unsigned subcond = 0;
if(__powerlaw_index > 0) {
double critical_frequency =
__zone.__spin_frequency_breaks[__powerlaw_index - 1];
result[subcond++] = (
(__zone.spin_frequency() - critical_frequency)
/
critical_frequency
);
} if(__powerlaw_index < __zone.__spin_frequency_breaks.size()) {
double critical_frequency =
__zone.__spin_frequency_breaks[__powerlaw_index];
result[subcond] = (
(__zone.spin_frequency() - critical_frequency)
/
critical_frequency
);
}
return result;
}
void LagSpinBreakCondition::reached(
short
#ifndef NDEBUG
deriv_sign
#endif
,
unsigned index)
{
assert(index < __num_subconditions);
if(__powerlaw_index > 0 && index == 0) {
assert(deriv_sign == -1);
--__powerlaw_index;
--__zone.__spin_index;
} else {
assert(deriv_sign == 1);
assert(__powerlaw_index < __zone.__spin_frequency_breaks.size());
++__powerlaw_index;
++__zone.__spin_index;
}
set_num_subconditions();
}
short LagSpinBreakCondition::expected_crossing_deriv_sign(
unsigned index
) const
{
if(index == 1 || __powerlaw_index == 0) {
assert(__powerlaw_index
<
__zone.__spin_frequency_breaks.size());
return 1;
} else {
return -1;
}
}
std::string LagSpinBreakCondition::describe(int index) const
{
std::ostringstream description;
description << (__primary ? "Primary" : "Secondary")
<< " body, zone "
<< __zone_index
<< " spin frequency leaving the interval ";
if(__powerlaw_index > 0 && index <= 0)
description
<< __zone.__spin_frequency_breaks[__powerlaw_index - 1]
<< " < ";
description << " |Wspin| ";
if(
__powerlaw_index < __zone.__spin_frequency_breaks.size()
&&
(
index < 0
||
index == static_cast<int>(__num_subconditions) - 1
)
)
description << " < "
<< __zone.__spin_frequency_breaks[__powerlaw_index];
description << std::endl;
return description.str();
}
}//End Evolve namespace