10 #define BUILDING_LIBRARY 17 const double MIN_RELATIVE_STEP = (
20 10.0 * std::numeric_limits<double>::epsilon()
24 const double *parameters,
28 void **input_params =
static_cast<void **
>(system_mode);
40 double *param_derivs,
double *age_derivs,
void *system_mode)
42 void **input_params =
static_cast<void **
>(system_mode);
58 std::streamsize orig_precision=os.precision();
60 std::ios_base::fmtflags orig_flags=os.flags();
61 os.setf(std::ios_base::scientific);
63 os <<
"Stored stop condition information:" << std::endl
64 << std::setw(20) <<
"Age:";
71 os << std::setw(28) << *age_i;
78 os << std::endl << hline << std::endl;
86 os << std::setw(13) <<
"Condition[" 94 bool marked_skip_extremum=
false;
95 for(std::list< std::valarray<double> >::const_iterator
104 os <<
"z"; marked=
true;
107 && !marked_skip_extremum) {
108 os <<
"e"; marked_skip_extremum=
true; marked=
true;
109 }
else os << (marked ?
"-" :
" ");
110 os << (marked ?
">" :
" ");
111 os << std::setw(25) << (*cond_i)[i];
116 os << std::setw(13) <<
"Derivative[" << std::setw(5) << i
118 for(std::list< std::valarray<double> >::const_iterator
125 os << std::setw(28) << (*deriv_i)[i];
130 os.precision(orig_precision);
131 os.flags(orig_flags);
143 const std::valarray<double> ¤t_stop_cond,
144 const std::valarray<double> ¤t_stop_deriv)
147 std::list< std::valarray<double> >::iterator
151 age_i++; cond_i++; deriv_i++;
170 std::valarray<double> &orbit)
199 __skip_history_extremum[i]
238 size_t num_points = std::min(
249 std::list< std::valarray<double> >::const_iterator
252 int go_back = (
static_cast<int>(num_points)
255 go_back = std::max(go_back, (crossing ? 1 : 2));
256 size_t failed_back = 0;
257 for(
int i = 0; i <
go_back; ++i) {
269 if(go_back - failed_back < (crossing ? 1 : 2))
283 num_points - (crossing ? 2 : 3));
284 int history_limit = 0;
300 max_left_shift = std::min(history_limit, max_left_shift);
301 for(
int i = 0; i < max_left_shift; i++) {
304 (interval.last_age() - interval.first_age())
306 result.last_age() - result.first_age()
314 size_t condition_index
324 std::list< std::valarray<double> >::const_iterator stop_cond_i =
326 double pre1_cond = (*(--stop_cond_i))[condition_index],
327 pre2_cond = (*(--stop_cond_i))[condition_index],
330 std::abs(pre1_cond) > std::abs(pre2_cond)
332 std::abs(pre1_cond) > std::abs(post_cond)
335 !std::isfinite(pre1_cond)
337 !std::isfinite(pre2_cond)
339 !std::isfinite(post_cond)
351 double t0 = stop_interval.
age(),
353 t1 = (++stop_interval).age(),
355 t2 = (++stop_interval).age(),
357 abs_c0 = std::abs(c0),
358 abs_c1 = std::abs(c1),
359 abs_c2 = std::abs(c2);
361 const double min_fractional_diff = (
364 std::numeric_limits<double>::epsilon()
367 bool ignore_10_diff = (std::abs(c1 - c0) / std::max(abs_c0, abs_c1)
369 min_fractional_diff),
370 ignore_21_diff = (std::abs(c2 - c1) / std::max(abs_c1, abs_c2)
372 min_fractional_diff);
376 if((c1 - c0) * (c2 - c1) > 0 || ignore_10_diff || ignore_21_diff)
380 result.
x() = Core::quadratic_extremum(t0, c0, t1, c1, t2, c2,
383 double t3 = (++stop_interval).age(),
385 abs_c3 = std::abs(c3);
386 bool ignore_32_diff = (
387 std::abs(c3 - c2) / std::max(abs_c3, abs_c2)
393 (c1 - c0) * (c2 - c1) > 0
395 abs_c1 >= std::max(abs_c0, abs_c2)
403 (c2 - c1) * (c3 - c2) > 0
405 abs_c2 >= std::max(abs_c1, abs_c3)
419 std::abs(c1) <= std::abs(c0)
421 std::abs(c1) <= std::abs(c2)
435 "Searching for extremum among monotonic stopping condition " 436 "values in OrbitSolver::extremum_from_history_no_deriv." 438 result.
x() = Core::cubic_extremum(t0, c0, t1, c1, t2, c2, t3, c3,
440 range_low, range_high);
446 size_t condition_index)
const 461 if(next_stop_cond * prev_stop_cond <= 0)
468 next_stop_cond * next_stop_deriv < 0
470 next_stop_deriv * prev_stop_deriv >= 0
491 if(stop_interval.
num_points() < 2)
return Core::Inf;
492 double t0 = stop_interval.
age(),
494 t1 = (++stop_interval).age(),
497 return Core::estimate_zerocrossing(t0, c0, t1, c1);
498 double t2 = (++stop_interval).age(),
500 double range_low = Core::NaN,
501 range_high = Core::NaN;
502 short crossing_sign =
506 if(c0 * c1 <= 0 && c1 * crossing_sign > 0) {
509 }
else if(c1 * c2 <= 0 && c2 * crossing_sign > 0) {
514 assert(!std::isnan(range_low) && !std::isnan(range_high));
515 return Core::quadratic_zerocrossing(
516 t0, c0, t1, c1, t2, c2, range_low, range_high
519 double t3 = (++stop_interval).age(),
521 if(std::isnan(range_low)) {
525 assert(c3 * crossing_sign > 0);
527 return Core::cubic_zerocrossing(
528 t0, c0, t1, c1, t2, c2, t3, c3, range_low, range_high
547 next_stop_cond * prev_stop_cond > 0
579 return Core::estimate_zerocrossing(prev_age,
603 (stop_reason!=
NO_STOP && stop_cond_type==stop_reason)
609 (1.0+std::numeric_limits<double>::epsilon())
645 previous_age * MIN_RELATIVE_STEP
655 std::cerr <<
"From t = " << previous_age
656 <<
", stepped to t = " << current_age
657 <<
", stop at t = " << stop_info.
stop_age()
658 <<
", must be at least: " << previous_age * MIN_RELATIVE_STEP
665 std::cerr <<
"Failed to meet precision for " 682 const std::valarray<double> &derivatives,
683 const std::valarray<double> &expansion_errors
686 double max_error_ratio = 0.0;
688 unsigned max_ratio_index = 0;
690 for(
unsigned i = 0; i < derivatives.size(); ++i) {
691 double error_ratio = (
692 std::abs(expansion_errors[i])
696 assert(error_ratio >= 0);
697 if(error_ratio > 1.0) {
699 std::cerr <<
"Expansion ratio for parameter " << i
700 <<
" = " << error_ratio
701 <<
" suggest increasing e order!" 706 if(error_ratio > max_error_ratio) {
707 max_error_ratio = error_ratio;
714 std::cerr <<
"O(e) downgrade threshold = " 716 <<
", max error ratio = " 724 std::cerr <<
"Suggest decreasing e order." << std::endl;
729 std::cerr <<
"Suggest e order is fine." << std::endl;
737 const std::valarray<double> &orbit,
738 const std::valarray<double> &derivatives,
739 const std::valarray<double> &expansion_errors,
742 bool ignore_e_order_decrease
745 for(
unsigned i = 0; i < orbit.size(); ++i)
749 (evolution_mode == Core::BINARY && orbit[0] <= 0)
752 std::cerr <<
"Bad orbit: " << orbit << std::endl;
760 int adjust_e_order = 0;
761 if(evolution_mode == Core::BINARY) {
764 if(adjust_e_order > 0)
772 std::valarray<double> current_stop_cond(
775 std::valarray<double> current_stop_deriv;
776 current_stop_cond = (*__stopping_conditions)(evolution_mode,
786 std::cerr << std::string(77,
'@') << std::endl;
788 std::cerr <<
"Decreasing e_order is " 789 << (ignore_e_order_decrease ?
"not" :
"")
798 cond_ind < current_stop_cond.size()
802 double stop_cond_value = current_stop_cond[cond_ind],
806 bool crossed_zero =
false;
807 if(std::abs(crossing_precision) >= std::abs(stop_cond_value)) {
808 crossing_precision = stop_cond_value;
812 double extremum_precision;
813 if(std::isnan(extremum.
y())) extremum_precision = Core::NaN;
815 extremum_precision = (
817 std::abs(extremum.
y() - stop_cond_value),
818 std::abs(extremum.
y()
823 std::abs(extremum.
y())
825 bool is_crossing = crossing_age <= extremum.
x();
826 short deriv_sign = 0;
827 if(is_crossing) deriv_sign = (stop_cond_value > 0 ? 1 : -1);
829 stop_info.
stop_age() = std::min(crossing_age, extremum.
x());
832 : extremum_precision);
839 std::cerr <<
"Condition " << cond_ind <<
" " 847 stop_info) || is_crossing)
853 std::cerr <<
"SELECTED" << std::endl;
855 std::cerr <<
"NOT SELECTED!" << std::endl;
874 !ignore_e_order_decrease
883 std::cerr <<
"Step to age = " 885 <<
" deemed unacceptable: " 897 std::valarray<double> &orbit,
910 <<
"Reverting step from t = " 924 last_good_t * MIN_RELATIVE_STEP
927 std::cerr <<
"Stepped only " 942 step_size = 0.1 * (max_next_t - t);
948 std::valarray<double> &orbit,
954 size_t nargs = orbit.size();
956 std::cerr <<
"Starting evolution leg in " << evolution_mode
957 <<
" from t=" << system.
age() <<
" with initial orbit:\n";
958 for(
size_t i = 0; i < nargs; ++i) {
959 if(i) std::cerr <<
", ";
960 std::cerr <<
"\t" << orbit[i] << std::endl;
962 std::cerr << std::endl;
963 std::cerr <<
"Stopping conditions:" << std::endl
968 const gsl_odeiv2_step_type *step_type = gsl_odeiv2_step_rkf45;
970 gsl_odeiv2_step *step = gsl_odeiv2_step_alloc(step_type, nargs);
971 gsl_odeiv2_control *step_control = gsl_odeiv2_control_standard_new(
977 gsl_odeiv2_evolve *evolve = gsl_odeiv2_evolve_alloc(nargs);
979 void *sys_mode[2]={&system, &evolution_mode};
984 double t=system.
age();
985 std::valarray<double> derivatives(nargs),
986 expansion_errors(nargs),
987 param_derivatives(nargs),
988 age_derivatives(nargs);
1002 double step_size = std::min(0.1 * (max_age - t),
1007 bool first_step =
true;
1010 double max_next_t = std::min(t + max_step, max_age);
1011 int status=GSL_SUCCESS;
1012 bool step_rejected=
false;
1015 std::cerr <<
"Attempting step from t = " << t
1016 <<
" not to miss t = " << max_next_t
1017 <<
", suggested step = " << step_size
1019 for(
size_t i=0; i<nargs; ++i) {
1020 if(i) std::cerr <<
", ";
1021 std::cerr <<
"\t" << orbit[i] << std::endl;
1023 std::cerr << std::endl;
1027 step_size = std::max(step_size,
1028 3.0 * (MIN_RELATIVE_STEP * t - t));
1029 status = gsl_odeiv2_evolve_apply(evolve,
1038 if (status == GSL_FAILURE) {
1040 std::cerr <<
"Failed, (presume zero step size)!" 1044 }
else if (status != GSL_SUCCESS && status != GSL_EDOM) {
1045 std::ostringstream msg;
1046 msg <<
"GSL signaled failure while evolving (error code " <<
1056 std::ostringstream msg;
1057 msg <<
"Exceeded evolution time limit of " 1062 if(status == GSL_SUCCESS) {
1066 std::cerr <<
"Succeeded! Now t = " << t << std::endl;
1067 #ifdef VERBOSE_DEBUG 1068 std::cerr <<
"GSL suggested new step size:" 1081 &(expansion_errors[0]),
1104 , (status == GSL_EDOM ?
"EDOM error" :
"bad step")
1107 gsl_odeiv2_evolve_reset(evolve);
1108 step_rejected =
true;
1110 if(!first_step && t < from_t * MIN_RELATIVE_STEP) {
1112 std::cerr <<
"Stepped only " 1119 step_rejected=
false;
1137 if(!step_rejected) {
1139 std::cerr <<
"Stepped to t = " << t << std::endl;
1144 std::cerr <<
"Stop: " << stop
1147 <<
"max age: " << max_age
1167 std::cerr <<
"Breaking for = " << stop << std::endl;
1179 gsl_odeiv2_evolve_free(evolve);
1180 gsl_odeiv2_control_free(step_control);
1181 gsl_odeiv2_step_free(step);
1190 #ifdef EXTERNAL_CONDITION 1191 (*result) |=
new EXTERNAL_CONDITION;
1195 for(
size_t cond_ind = 0; cond_ind <
__stop_info.size(); ++cond_ind)
1198 __stop_info[cond_ind].stop_condition_index() = cond_ind;
1205 const std::list<double> &required_ages)
1208 std::cerr <<
"Determining next stop age: " << std::endl;
1212 std::cerr <<
"Next system stop age: " << result << std::endl;
1214 if(required_ages.size() == 0)
return result;
1216 static std::list<double>::const_iterator
1217 next_required_age = required_ages.begin();
1218 if(age <= required_ages.front())
1219 next_required_age = required_ages.begin();
1221 next_required_age != required_ages.end()
1223 age == *next_required_age
1225 ++next_required_age;
1227 next_required_age != required_ages.end()
1229 result > *next_required_age
1231 result = *next_required_age;
1233 std::cerr <<
"Required ages change that to: " << result << std::endl;
1244 std::cerr <<
"Stopped due to condition at t = " 1249 std::vector<StopInformation>::const_iterator stop_i =
1255 stop_i->is_crossing()
1258 stop_i->stop_age() < stop_age
1261 stop_i->stop_reason() == stop_reason
1268 std::cerr <<
"Triggered condition: " 1270 stop_i->stop_condition_index()
1275 stop_i->deriv_sign_at_crossing(),
1276 stop_i->stop_condition_index()
1284 const std::valarray<double> &orbit,
1290 std::cerr <<
"Adjusting eccentricity order at t =" 1294 assert(evolution_mode == Core::BINARY);
1297 starting_e_order = e_order;
1298 std::valarray<double> expansion_errors(orbit.size()),
1299 derivatives(orbit.size());
1302 int adjust_e_order, last_adjustment = 0;
1312 &(expansion_errors[0]),
1318 std::cerr <<
"Suggested adjustment: " << adjust_e_order << std::endl;
1326 std::ostringstream msg;
1327 msg <<
"Maximum available eccentricity expansion order of " 1329 << (
" is insufficient to ensure evolution to the " 1330 "specified precisoin.");
1334 if(adjust_e_order || must_increase) {
1338 }
else if(e_order == 0 && adjust_e_order < 0)
1341 e_order += adjust_e_order;
1342 if(adjust_e_order > 0)
1347 e_order == starting_e_order
1357 std::cerr <<
"Reverted to eccentricity expansion order of ";
1359 std::cerr <<
"Trying eccentricity expansion order of ";
1363 std::cerr << e_order << std::endl;
1365 last_adjustment = adjust_e_order;
1366 if(must_increase && adjust_e_order <= 0)
break;
1368 }
while(adjust_e_order && e_order != starting_e_order);
1370 if(e_order != starting_e_order) {
1373 std::cerr <<
"Adjusted eccentricity expansion order to " 1388 double required_precision,
1389 bool print_progress) :
1403 const std::list<double> &required_ages,
1407 std::cerr <<
"Calculating evolution from t = " << system.
age()
1408 <<
" to t = " <<
__end_age << std::endl;
1417 double last_age = system.
age();
1418 std::valarray<double> orbit;
1422 if(evolution_mode == Core::BINARY)
1428 while(last_age < stop_evol_age) {
1435 std::cerr <<
"Next stop age: " << next_stop_age << std::endl;
1447 std::cerr <<
"Stop information: " 1452 last_age = next_stop_age;
1453 if(last_age < stop_evol_age) {
1472 <<
"At t=" << last_age
1473 <<
", changing evolution mode from " << old_evolution_mode
1474 <<
" with " << old_locked_zones
1475 <<
" zones locked ";
1480 <<
"to " << evolution_mode
1484 <<
"Transforming orbit from: ";
1489 std::cerr <<
" to " << orbit << std::endl;
1493 evolution_mode == Core::BINARY
1495 old_evolution_mode != Core::BINARY
Maximum allowed step size decreased below machine precision.
virtual void add_to_evolution()
Appends the state defined by last configure(), to the evolution.
int differential_equations(double age, const double *parameters, Core::EvolModeType evolution_mode, double *differential_equations, bool expansion_error=false)
The differential equation and jacobian for the evolution of the system.
OrbitSolver(double max_age, double required_precision, bool print_progress=false)
Prepare to solve for the orbital evolution.
double __runtime_limit
Max number of seconds current evolution is allowed to run.
Function arguments do not satisfy some requirement.
void operator()(BinarySystem &system, double max_step=Core::Inf, const std::list< double > &required_ages=std::list< double >(), double max_runtime=0)
Actually solves the given differential equation with the given boundary conditions.
void reset(BinarySystem &system)
Clears any previously calculated evolution.
ExtremumInformation extremum_from_history_no_deriv(size_t condition_index) const
Estimates the value and age of an extremum of a stopping condition for which no derivative informatio...
double __precision
The precision required of the solution.
ExtremumInformation extremum_from_history(size_t condition_index) const
Estimates the value and age of an extremum of a stopping condition for which derivative information i...
The spin-orbit lock can no longer be maintaned.
void reject_step(double &age, StopInformation &stop, BinarySystem &system, std::valarray< double > &orbit, double &max_next_t, double &step_size, std::string reason)
Handle the situation when the last step has to be rejected.
std::list< Core::EvolModeType > __tabulated_evolution_modes
The evolution mode corresponding to the matching tabulated age.
virtual StoppingConditionType type(unsigned index=0) const =0
What event is the index-th stopping sub-condition associated with.
std::list< std::valarray< double > > __stop_cond_history
Past values of the stop conditions.
The error due to truncating the eccentricity expansion is too small.
virtual size_t num_subconditions() const
The number of subconditions in the current condition.
virtual double next_stop_age() const
The next age when the evolution needs to be stopped for a system change.
void initialize_skip_history(const StoppingCondition &stop_cond, StoppingConditionType stop_reason)
Initializes the skip_history_zerocrossing and skip_history_extremum arrays appropriately after a mode...
StopInformation update_stop_condition_history(double age, const std::valarray< double > &orbit, const std::valarray< double > &derivatives, const std::valarray< double > &expansion_errors, Core::EvolModeType evolution_mode, StoppingConditionType stop_reason=NO_STOP, bool ignore_e_order_decrease=false)
Updates stop_cond_history and stop_deriv_history after a GSL step, returning if/where the evolution n...
StoppingConditionType
The reasons for stopping the evolution currently supported.
Orientations of zones of bodies in a binary system.
time_t __evolution_start_time
When did the currently running evolution start.
std::list< std::valarray< double > > __stop_deriv_history
Past values of the stop condition derivatives.
Defines the OrbitSolver class, the various stopping conditions and a number of other classes used whi...
double go_back(double max_age, BinarySystem &system, std::valarray< double > &orbit)
Rewinds the evlution to the last step before the given age and returns the age of that step...
void add_to_evolution(double age, Core::EvolModeType evolution_mode, BinarySystem &system)
Adds the last step to the evolution.
virtual void reset_evolution()
Resets the evolution of the system.
double age() const
Returns the present age of the system in Gyr.
double crossing_from_history(size_t condition_index) const
Estimates the age at which a stopping condition with derivative information crossed zero...
CombinedStoppingCondition * get_stopping_condition(BinarySystem &system)
Returns the stopping conditions which end the given evolution mode and update __stop_info.
void output_history_and_discarded(std::ostream &os)
Generates a nicely formatted table of the contents of the discarded and history stopping condition in...
bool at_exact_condition(double previous_age, const StopInformation &stop_info)
Is the condition causing a stop match to within the required precision?
int check_expansion_error(const std::valarray< double > &derivatives, const std::valarray< double > &expansion_errors)
Return -1 if the expansion error is too small (e-order can safely be decreased, 0 if it is within ran...
unsigned number_locked_zones() const
How many zones on either body are currently locked.
virtual void reached_critical_age(double age)
Change the system as necessary at the given age.
static unsigned max_e_order()
The maximum eccentricity expansion order for which the expansion is known.
double stopping_age(double age, const BinarySystem &system, const std::list< double > &required_ages)
The age at which the evolution should stop next if no other stopping condition occurs.
The error due to truncating the eccentricity expansion is too large.
double __last_e_order_upgrade_age
The last age at which the eccentricity order was increased.
std::vector< StopInformation > __stop_info
double __e_order_downgrade_threshold
If the fractional error due to truncating the eccentricity series falls below this value times the ma...
StopInformation evolve_until(BinarySystem &system, double &max_age, std::valarray< double > &orbit, StoppingConditionType &stop_reason, double max_step, Core::EvolModeType evolution_mode)
Evolves a system until either some age cut-off is reached or some stopping condition crosses zero...
void reached_stopping_condition(double stop_age, StoppingConditionType stop_reason)
Handle a stop in the evolution due to at least one condition reaching a critical value.
int jacobian(double age, const double *parameters, Core::EvolModeType evolution_mode, double *param_derivs, double *age_derivs)
virtual short expected_crossing_deriv_sign(unsigned index=0) const
The expected sign of the derivative at the next zero-crossing.
virtual std::string describe(int index=-1) const =0
Overwrite with something returning a description of what the stopping condition is monitoring...
size_t num_points()
Returns the number of points in the interval.
A base class for all stopping conditions.
void clear_history()
Clears the current stopping condition history.
bool __print_progress
See print_progress argument of constructor.
virtual void rewind_evolution(unsigned nsteps)
Discards the last steps from the evolution.
std::list< std::valarray< double > > __stop_deriv_discarded
Discarded derivatives of the stop conditions.
Core::EvolModeType evolution_mode()
The evolution mode of last call to configure().
std::list< double > __discarded_stop_ages
The ages of steps which were discarded becauset they are past a zero or an extremum of a stopping con...
std::list< std::valarray< double > > __orbit_deriv_history
Past orbital derivatives.
EvolModeType
The various evolution modes.
virtual size_t num_subconditions() const
The number of subconditions in the current condition.
std::valarray< size_t > __skip_history_zerocrossing
The number of points at the start of the history to skip when lookng for a zero crossing for each con...
StopHistoryInterval select_stop_condition_interval(bool crossing, size_t cond_ind, size_t max_points) const
Selects a history interval for interpolating to a reason to stop the evolution.
int stellar_system_jacobian(double age, const double *orbital_parameters, double *param_derivs, double *age_derivs, void *system_mode)
A wrapper tha allows the stellar system jacobian to be passed to the GSL ODE solver.
double crossing_from_history_no_deriv(size_t condition_index) const
Estimates the age at which a stopping condition with no derivative information crossed zero...
double stop_condition_value(size_t condition_index) const
Returns the value of the stop condition with the given index for the current point.
virtual void change_e_order(unsigned new_e_order)
Change the eccentricity expansion order for all dissipative zones.
double __end_age
The last age for which evolution is required.
A class combining the the outputs of multiple stopping conditions.
StoppingConditionType type(unsigned index=0) const
What event is the index-th stopping sub-condition associated with.
std::list< double > __stop_history_ages
The ages at which the stop condition history is kept.
GSL step size decreased below machine precision.
void clear_discarded()
Removes all stored discarded stop condition information.
virtual CombinedStoppingCondition * stopping_conditions()
Conditions detecting the next possible doscontinuity in the evolution.
std::valarray< double > __skip_history_extremum
The age after which to look for extrema for each condition.
std::list< double > __tabulated_ages
The ages at which solution is tabulated.
double age() const
Returns the age of the current point.
std::list< std::valarray< double > > __orbit_history
Past orbits.
Describes a system of two bodies orbiting each other.
void insert_discarded(double age, const std::valarray< double > ¤t_stop_cond, const std::valarray< double > ¤t_stop_deriv)
Adds an entry in the discarded ages, stop conditions and derivatives.
virtual unsigned eccentricity_order() const
A collection of accepted and discarded evolution steps which contain some reason to stop...
StoppingCondition * __stopping_conditions
The current set of stopping conditions.
Core::EvolModeType fill_orbit(std::valarray< double > &orbit) const
Fills an array with the parameters expected by differential_equations() and jacobian(), returning the evolution mode.
std::list< std::valarray< double > > __stop_cond_discarded
Discarded values of the stop conditions.
bool acceptable_step(double current_age, double previous_age, const StopInformation &stop_info)
Updates the skip_history_zerocrossing and skip_history_extremum arrays appropriately after an accepta...
void adjust_eccentricity_order(BinarySystem &system, const std::valarray< double > &orbit, Core::EvolModeType evolution_mode, bool must_increase=false)
Increase/decrease the eccentricity expansion order until error is acceptable and return the new order...
int stellar_system_diff_eq(double age, const double *parameters, double *derivatives, void *system_mode)
A wrapper tha allows the stellar system differential equation to be passed to the GSL ODE solver...
virtual void reached(short deriv_sign, unsigned index=0)
Called when a stopping condition has been reached by the evolution.