14 const double zero = 0.0;
15 const double one = 1.0;
30 os <<
"SEMIMAJOR";
break;
32 os <<
"ECCENTRICITY";
break;
34 os <<
"CONV_INCLINATION";
break;
36 os <<
"RAD_INCLINATION";
break;
38 os <<
"CONV_PERIAPSIS";
break;
40 os <<
"RAD_PERIAPSIS";
break;
42 os <<
"CONV_ANGMOM";
break;
44 os <<
"RAD_ANGMOM";
break;
55 std::valarray<double>(Core::NaN, 2),
61 std::valarray<double>(),
67 std::valarray<double>(1.0, 1),
73 std::valarray<double>(2.0, 1),
79 std::valarray<double>(200.0, 1),
96 const double suppression_factor = 0.01;
98 std::vector<double> breaks(2);
99 breaks[0] = min_frequency;
100 breaks[1] = max_frequency;
102 std::vector<double> powerlaw_indices(3);
103 powerlaw_indices[0] = (
104 std::log(suppression_factor)
106 std::log(1.0 - decay_scale / min_frequency)
108 powerlaw_indices[1] = 0.0;
109 powerlaw_indices[2] = (
110 std::log(suppression_factor)
112 std::log(1.0 + decay_scale / max_frequency)
126 std::vector<double>(),
128 std::vector<double>(1, 0.0),
134 double wind_strength,
135 double wind_sat_freq,
136 double coupling_timescale,
137 double min_frequency,
138 double max_frequency,
159 const double *initial_Lstar,
161 double secondary_mass,
164 double secondary_radius,
166 double max_step_factor,
167 const std::list<double> required_ages)
175 secondary_mass *= Mjup_to_Msun;
176 secondary_radius *= Rjup_to_Rsun;
178 if(std::isnan(tsecondary)) tsecondary = tdisk;
181 (secondary_mass ? secondary_radius : 0.0));
204 double zeros[] = {0.0, 0.0};
206 if(tdisk <= TSTART) {
207 if(tsecondary <= TSTART) {
234 Core::LOCKED_SURFACE_SPIN);
238 double initial_inclinations[] = {initial_incl, 0.0, 0.0};
244 initial_inclinations,
250 (max_age - __system->age()) * max_step_factor,
257 std::vector< const std::list<double> *>
258 tabulated_real_quantities(NUM_REAL_QUANTITIES);
271 tabulated_real_quantities[RAD_INCLINATION] =
274 tabulated_real_quantities[RAD_PERIAPSIS] =
277 tabulated_real_quantities[RAD_ANGMOM] = &(
282 tabulated_real_quantities[RAD_INCLINATION] = NULL;
283 tabulated_real_quantities[RAD_PERIAPSIS] = NULL;
284 tabulated_real_quantities[RAD_ANGMOM] = NULL;
288 tabulated_real_quantities[CONV_INCLINATION] = &(
292 tabulated_real_quantities[CONV_PERIAPSIS] = &(
296 tabulated_real_quantities[CONV_ANGMOM] = &(
301 return tabulated_real_quantities;
305 const std::vector<
const std::list<double> * > &
306 tabulated_real_quantities,
307 std::vector<const Core::OneArgumentDiffFunction *>
308 expected_real_quantities,
316 const std::list<Core::EvolModeType> &tabulated_modes =
319 const std::list<bool> *tabulated_wind_sat =
322 unsigned num_ages = tabulated_real_quantities[
AGE]->size();
324 std::ostringstream msg_start;
325 std::ostringstream msg;
327 msg.setf(std::ios_base::scientific);
328 msg_start.precision(16);
329 msg_start.setf(std::ios_base::scientific);
330 msg << msg_start.str()
332 <<
" tabulated ages, ";
333 bool all_same_size =
true;
335 for(
unsigned q = 0; q <
AGE; ++q) {
336 if(tabulated_real_quantities[q]) {
337 msg << tabulated_real_quantities[q]->size()
344 tabulated_real_quantities[q]->size() == num_ages
349 msg << tabulated_modes.size() <<
" tabulated modes";
351 all_same_size = (all_same_size
353 tabulated_modes.size() == num_ages);
356 << tabulated_wind_sat->size()
357 <<
" tabulated wind saturations";
358 all_same_size = (all_same_size
360 tabulated_wind_sat->size() == num_ages);
364 if(debug_mode) std::cout << msg.str() << std::endl;
365 TEST_ASSERT_MSG(all_same_size, msg.str().c_str());
368 msg <<
"Expected age range: " << min_age <<
" to " << max_age
369 <<
", actual age range: " << tabulated_real_quantities[AGE]->front()
370 <<
" to " << tabulated_real_quantities[AGE]->back();
371 if(debug_mode) std::cout << msg.str() << std::endl;
374 tabulated_real_quantities[AGE]->front() == min_age
376 tabulated_real_quantities[AGE]->back() == max_age
381 std::vector< std::list<double>::const_iterator >
382 real_tabulated_iter(AGE);
383 for(
unsigned q = 0; q < AGE; ++q)
384 if(tabulated_real_quantities[q])
385 real_tabulated_iter[q] = tabulated_real_quantities[q]->begin();
386 std::list<Core::EvolModeType>::const_iterator
387 tabulated_mode_iter = tabulated_modes.begin();
388 std::list<bool>::const_iterator tabulated_wind_sat_iter;
390 tabulated_wind_sat_iter = tabulated_wind_sat->begin();
391 double last_checked_age = Core::NaN;
394 std::list<double>::const_iterator
395 age_i = tabulated_real_quantities[AGE]->begin();
396 age_i != tabulated_real_quantities[AGE]->end();
399 std::vector<double> expected_real_values(AGE);
400 for(
unsigned q = 0; q < AGE; ++q) {
401 expected_real_values[q] =
402 (*(expected_real_quantities[q]))(*age_i);
405 bool expected_wind_sat = expected_wind_mode(*age_i);
407 std::ostringstream age_msg_start;
408 age_msg_start.precision(16);
409 age_msg_start.setf(std::ios_base::scientific);
410 age_msg_start << msg_start.str()
411 <<
"age = " << *age_i
412 <<
", mode = " << *tabulated_mode_iter;
414 age_msg_start <<
", wind is ";
415 if(!(*tabulated_wind_sat_iter)) age_msg_start <<
" not ";
416 age_msg_start <<
"saturated";
418 for(
unsigned q = 0; q < AGE; ++q)
419 if(tabulated_real_quantities[q])
420 age_msg_start <<
", " 423 << *real_tabulated_iter[q];
426 msg << age_msg_start.str() <<
" age is out of range.";
427 TEST_ASSERT_MSG(*age_i >= min_age && *age_i <= max_age,
430 std::list<double>::const_iterator next_age_i = age_i;
434 next_age_i != tabulated_real_quantities[AGE]->end()
436 std::abs(*next_age_i - *age_i) < 1e-5
442 skipped = (*age_i == last_checked_age);
445 msg << age_msg_start.str() <<
": mode is not " 446 << expected_mode <<
", but " << *tabulated_mode_iter;
448 if(debug_mode) std::cout << msg.str() << std::endl;
449 if(!skipped && expected_mode != *tabulated_mode_iter) {
450 if(can_skip) skipped =
true;
451 else TEST_ASSERT_MSG(
false, msg.str().c_str());
456 msg << age_msg_start.str() <<
": wind is ";
457 if(!(*tabulated_wind_sat_iter)) msg <<
" not ";
458 msg <<
"saturated, but should";
459 if(!expected_wind_sat) msg <<
" not ";
461 if(debug_mode) std::cout << msg.str() << std::endl;
462 if(!skipped && expected_wind_sat != *tabulated_wind_sat_iter) {
463 if(can_skip) skipped =
true;
464 else TEST_ASSERT_MSG(
false, msg.str().c_str());
478 for(
unsigned q = 0; q < AGE; ++q) {
479 if(!tabulated_real_quantities[q])
continue;
481 msg << age_msg_start.str() <<
": " 484 << expected_real_values[q]
486 << *real_tabulated_iter[q]
488 << (*real_tabulated_iter[q]) - expected_real_values[q];
489 if(debug_mode) std::cout << msg.str() << std::endl;
494 expected_real_values[q],
502 TEST_ASSERT_MSG(
false, msg.str().c_str());
506 last_checked_age = *age_i;
508 std::cerr <<
"Skipped checks for t = " << *age_i
510 for(
unsigned q = 0; q < AGE; ++q)
511 if(tabulated_real_quantities[q])
512 ++(real_tabulated_iter[q]);
513 if(
__star) ++tabulated_wind_sat_iter;
514 ++tabulated_mode_iter;
520 double *initial_Lstar,
522 double wind_sat_freq,
523 double core_env_coupling_time,
524 std::vector<const Core::OneArgumentDiffFunction *>
525 &expected_real_quantities,
532 single_mode.
add_break(TSTART, Core::SINGLE);
533 binary_mode.
add_break(TSTART, Core::BINARY);
538 core_env_coupling_time,
548 expected_real_quantities[
SEMIMAJOR] = &nan_func;
550 expected_real_quantities[CONV_INCLINATION] = &zero_func;
551 expected_real_quantities[RAD_INCLINATION] = &zero_func;
552 expected_real_quantities[CONV_PERIAPSIS] = &zero_func;
553 expected_real_quantities[RAD_PERIAPSIS] = &zero_func;
556 expected_real_quantities,
563 if(initial_Lstar[0] == 0)
return;
565 for(
double phase_lag = 0.0; phase_lag < 1.5; phase_lag += 1.0)
567 double mplanet = 0.0;
568 mplanet < 1.5 - phase_lag;
578 core_env_coupling_time,
589 expected_real_quantities[
SEMIMAJOR] = &one_func;
592 expected_real_quantities,
610 expected_real_quantities[
SEMIMAJOR] = &two_hundred_func;
612 expected_real_quantities,
629 std::vector<const Core::OneArgumentDiffFunction *>
632 double secondary_mass,
636 std::vector<const Core::OneArgumentDiffFunction *>
637 expected_real_quantities(NUM_REAL_QUANTITIES - 1);
639 double msecondary_si = (secondary_mass
652 msecondary_si / mprimary_si
675 a6p5_offset = std::pow(2.0, 6.5) + 6.5 * alpha;
676 a0 = std::pow(a6p5_offset, 1.0 / 6.5);
679 a6p5_offset = std::pow(a0, 6.5);
682 std::valarray<double> a6p5_poly_coef(2);
683 a6p5_poly_coef[0] = a6p5_offset;
684 a6p5_poly_coef[1] = (decaying ? -1.0 : 1.0) * 6.5 * alpha;
700 (decaying ? 0.0 : -1e5) - std::sqrt(a0),
712 expected_real_quantities[CONV_INCLINATION] = &zero_func;
713 expected_real_quantities[RAD_INCLINATION] = &zero_func;
714 expected_real_quantities[CONV_PERIAPSIS] = &zero_func;
715 expected_real_quantities[RAD_PERIAPSIS] = &zero_func;
721 expected_real_quantities[RAD_ANGMOM] = &zero_func;
723 return expected_real_quantities;
727 std::vector<const Core::OneArgumentDiffFunction *>
728 test_OrbitSolver::calculate_expected_disklocked_to_fast_to_locked(
734 bool include_disk_lock
737 const double Q = std::pow(10.0, lgQ),
767 Core::AstroConst::solar_mass
778 Core::AstroConst::solar_mass
788 a6p5_offset = (std::pow(async, 6.5)
790 6.5 * alpha * tsync),
791 a_formation=std::pow(
792 a6p5_offset + 6.5 * alpha * tdisk,
798 (std::sqrt(a_formation) - std::sqrt(async))
800 (beta * (std::pow(async, -1.5)
802 0.5 * std::pow(a_formation, -1.5)))
805 0.5 * beta / std::pow(a_formation, 1.5)
810 10.0 * std::numeric_limits<double>::epsilon()
813 wlocked = beta / std::pow(async, 1.5);
815 std::valarray<double> a6p5_poly_coef(2);
816 a6p5_poly_coef[0] = a6p5_offset;
817 a6p5_poly_coef[1] = 6.5 * alpha;
825 std::valarray<double>(Ic * wdisk, 1),
830 std::valarray<double>(Ic * wlocked, 1),
835 std::valarray<double>(Core::NaN, 2),
840 std::valarray<double>(async, 1),
845 std::valarray<double>(),
850 std::valarray<double>(),
871 -Ic * wdisk / Lscale - std::sqrt(a_formation), 0
888 if(include_disk_lock) {
892 zero_quantity = &zero_func;
894 zero_quantity = zero_e;
905 std::vector<const Core::OneArgumentDiffFunction *>
906 expected_real_quantities(NUM_REAL_QUANTITIES - 1);
908 expected_real_quantities[
SEMIMAJOR] = a_evol;
910 expected_real_quantities[CONV_INCLINATION] = zero_quantity;
911 expected_real_quantities[RAD_INCLINATION] = zero_quantity;
912 expected_real_quantities[CONV_PERIAPSIS] = zero_quantity;
913 expected_real_quantities[RAD_PERIAPSIS] = zero_quantity;
914 expected_real_quantities[CONV_ANGMOM] = Lconv_evol;
915 expected_real_quantities[RAD_ANGMOM] = zero_quantity;
917 return expected_real_quantities;
920 std::vector<const Core::OneArgumentDiffFunction *>
921 test_OrbitSolver::calculate_expected_polar_1_0(
double tdisk,
926 double aorb = std::pow(
946 std::valarray<double>(Core::NaN, 1),
951 std::valarray<double>(aorb, 1),
956 std::valarray<double>(),
961 std::valarray<double>(),
966 std::valarray<double>(M_PI / 2.0, 1),
991 conv_incl_evol->
add_piece(disk_zero_evol);
994 rad_incl_evol->
add_piece(disk_zero_evol);
997 std::vector<const Core::OneArgumentDiffFunction *>
998 expected_real_quantities(NUM_REAL_QUANTITIES - 1);
1000 expected_real_quantities[
SEMIMAJOR] = a_evol;
1002 expected_real_quantities[CONV_INCLINATION] = conv_incl_evol;
1003 expected_real_quantities[RAD_INCLINATION] = rad_incl_evol;
1004 expected_real_quantities[CONV_PERIAPSIS] = &zero_func;
1005 expected_real_quantities[RAD_PERIAPSIS] = &zero_func;
1006 expected_real_quantities[CONV_ANGMOM] =
1008 std::valarray<double>(wstar, 1),
1013 expected_real_quantities[CONV_ANGMOM]
1015 expected_real_quantities[RAD_ANGMOM] = &one_func;
1017 return expected_real_quantities;
1020 std::vector<const Core::OneArgumentDiffFunction *>
1021 test_OrbitSolver::calculate_expected_polar_2_0(
double tdisk,
1025 double &lconv_decay_rate,
1028 semimajor = std::pow(
1045 lconv_decay_rate = (
1063 std::pow(Core::AstroConst::solar_radius, 5)
1069 std::pow(Core::AstroConst::solar_radius, 2)
1093 semimajor * semimajor
1097 double lconv_offset = lconv_decay_rate * tdisk;
1099 std::valarray<double> spindown_coef(2);
1100 spindown_coef[0] = wstar + lconv_decay_rate * tdisk;
1101 spindown_coef[1] = - lconv_decay_rate;
1103 std::valarray<double> conv_cosinc_numer_coef(3),
1104 conv_cosinc_denom_coef(2),
1105 rad_cosinc_numer_coef(3),
1106 rad_cosinc_denom_coef(3);
1107 conv_cosinc_numer_coef[0] = - (
1108 (2.0 * wstar + lconv_offset) * lconv_offset
1110 conv_cosinc_numer_coef[1] = 2.0 * wstar * lconv_decay_rate;
1111 conv_cosinc_numer_coef[2] = -std::pow(lconv_decay_rate, 2);
1113 conv_cosinc_denom_coef[0] = 2.0 * lorb * (wstar + lconv_offset);
1114 conv_cosinc_denom_coef[1] = -2.0 * lconv_decay_rate * lorb;
1116 conv_cosinc_numer_coef[0] += conv_cosinc_denom_coef[0];
1117 conv_cosinc_numer_coef[1] += conv_cosinc_denom_coef[1];
1119 rad_cosinc_numer_coef[0] = - 2.0 * lorb * lconv_decay_rate * tdisk;
1120 rad_cosinc_numer_coef[1] = 2.0 * lorb * lconv_decay_rate;
1122 rad_cosinc_denom_coef[0] = (2.0 * lorb * lorb
1124 2.0 * wstar * lconv_decay_rate * tdisk
1126 std::pow(lconv_decay_rate * tdisk, 2));
1127 rad_cosinc_denom_coef[1] =
1128 2.0 * lconv_decay_rate * (worb + lconv_decay_rate * tdisk);
1129 rad_cosinc_denom_coef[2] = - std::pow(lconv_decay_rate, 2);
1131 rad_cosinc_numer_coef += rad_cosinc_denom_coef;
1136 std::valarray<double>(Core::NaN, 1),
1142 std::valarray<double>(semimajor, 1),
1148 std::valarray<double>(),
1154 std::valarray<double>(2.0, 1),
1158 *conv_cosinc_binary_numer =
1160 conv_cosinc_numer_coef,
1163 *conv_cosinc_binary_denom =
1165 conv_cosinc_denom_coef,
1169 *rad_cosinc_binary_numer =
1171 rad_cosinc_numer_coef,
1175 *rad_cosinc_binary_denom =
1177 rad_cosinc_denom_coef,
1183 std::valarray<double>(wstar, 1),
1205 conv_cosinc_binary_numer,
1206 conv_cosinc_binary_denom
1210 rad_cosinc_binary_numer,
1211 rad_cosinc_binary_denom
1232 conv_cosinc_evol->
add_piece(disk_cosinc_evol);
1233 conv_cosinc_evol->
add_piece(conv_cosinc_binary);
1235 rad_cosinc_evol->
add_piece(disk_cosinc_evol);
1236 rad_cosinc_evol->
add_piece(rad_cosinc_binary);
1241 std::vector<const Core::OneArgumentDiffFunction *>
1242 expected_real_quantities(NUM_REAL_QUANTITIES - 1);
1244 expected_real_quantities[
SEMIMAJOR] = a_evol;
1246 expected_real_quantities[CONV_INCLINATION] = conv_cosinc_evol;
1247 expected_real_quantities[RAD_INCLINATION] = rad_cosinc_evol;
1248 expected_real_quantities[CONV_PERIAPSIS] = &zero_func;
1249 expected_real_quantities[RAD_PERIAPSIS] = &zero_func;
1250 expected_real_quantities[CONV_ANGMOM] = lconv_evol;
1251 expected_real_quantities[RAD_ANGMOM] = &one_func;
1253 return expected_real_quantities;
1256 std::vector<const Core::OneArgumentDiffFunction *>
1257 test_OrbitSolver::calculate_expected_oblique_m_0(
1262 double initial_wstar,
1267 assert(m == 1 || m == 2);
1268 double aorb = std::pow(
1285 double lorb = (Mjup_to_Msun
1287 (1.0 + Mjup_to_Msun)
1293 double ltot = std::sqrt(
1294 std::pow(initial_wstar, 2)
1296 2.0 * initial_wstar * lorb * std::cos(initial_inc)
1301 min_wstar = ltot - lorb;
1303 double linear_quantity_rate = (
1321 std::pow(Core::AstroConst::solar_radius, 5)
1327 std::pow(Core::AstroConst::solar_radius, 2)
1339 std::valarray<double>(Core::NaN, 1),
1347 std::valarray<double>(aorb, 1),
1355 std::valarray<double>(),
1380 linear_quantity_rate
1389 linear_quantity_rate / 2.0
1407 std::vector<const Core::OneArgumentDiffFunction *>
1408 expected_real_quantities(NUM_REAL_QUANTITIES - 1);
1409 expected_real_quantities[
SEMIMAJOR] = a_evol;
1411 expected_real_quantities[CONV_INCLINATION] = conv_obliq_evol;
1412 expected_real_quantities[RAD_INCLINATION] = rad_obliq_evol;
1413 expected_real_quantities[CONV_PERIAPSIS] = &zero_func;
1414 expected_real_quantities[RAD_PERIAPSIS] = &zero_func;
1415 expected_real_quantities[CONV_ANGMOM] = lconv_evol;
1416 expected_real_quantities[RAD_ANGMOM] = &one_func;
1418 return expected_real_quantities;
1421 void test_OrbitSolver::test_disk_locked_no_stellar_evolution()
1425 StellarEvolution::make_no_evolution();
1432 expected_evol_mode.
add_break(TSTART, Core::LOCKED_SURFACE_SPIN);
1435 expected_wind_mode.
add_break(TSTART,
false);
1437 std::vector<const Core::OneArgumentDiffFunction *>
1438 expected_real_quantities(NUM_REAL_QUANTITIES - 1);
1439 expected_real_quantities[
SEMIMAJOR] = &nan_func;
1441 expected_real_quantities[CONV_INCLINATION] = &zero_func;
1442 expected_real_quantities[RAD_INCLINATION] = &zero_func;
1443 expected_real_quantities[CONV_PERIAPSIS] = &zero_func;
1444 expected_real_quantities[RAD_PERIAPSIS] = &zero_func;
1445 expected_real_quantities[CONV_ANGMOM] = &one_func;
1446 expected_real_quantities[RAD_ANGMOM] = &one_func;
1450 expected_real_quantities,
1462 -std::exp(TSTART/2.0),
1466 expected_real_quantities,
1472 delete expected_real_quantities[RAD_ANGMOM];
1475 TEST_ASSERT_MSG(
false, (std::string(
"Unexpected exception thrown: ")+
1477 }
catch (std::exception &ex) {
1478 TEST_ASSERT_MSG(
false, (std::string(
"Unexpected exception thrown: ")+
1479 ex.what()).c_str());
1483 void test_OrbitSolver::test_disk_locked_with_stellar_evolution()
1487 StellarEvolution::make_linear_I_evolution();
1492 expected_evol_mode.
add_break(TSTART, Core::LOCKED_SURFACE_SPIN);
1495 expected_wind_mode.
add_break(TSTART,
false);
1497 std::valarray<double> temp_array=std::valarray<double>(1.0, 2);
1504 std::vector<const Core::OneArgumentDiffFunction *>
1505 expected_real_quantities(NUM_REAL_QUANTITIES - 1);
1506 expected_real_quantities[
SEMIMAJOR] = &nan_func;
1508 expected_real_quantities[CONV_INCLINATION] = &zero_func;
1509 expected_real_quantities[RAD_INCLINATION] = &zero_func;
1510 expected_real_quantities[CONV_PERIAPSIS] = &zero_func;
1511 expected_real_quantities[RAD_PERIAPSIS] = &zero_func;
1512 expected_real_quantities[CONV_ANGMOM] =
1514 std::valarray<double>(1.0, 2),
1518 expected_real_quantities[RAD_ANGMOM] =
1521 double initial_Lrad = TSTART - 1 + std::exp(-TSTART / 2.0);
1527 expected_real_quantities,
1533 delete expected_real_quantities[CONV_ANGMOM];
1534 delete expected_real_quantities[RAD_ANGMOM];
1541 std::valarray< std::valarray<double> > Ic_arr(
1542 std::valarray<double>(1.0, 1),
1545 Ic_arr[1][0]=-1.0/6.0;
1548 std::valarray< std::valarray<double> >(
1549 std::valarray<double>(1.0, 1),
1553 std::valarray< std::valarray<double> >(
1554 std::valarray<double>(1.0/6.0, 1),
1557 std::valarray< std::valarray<double> >(
1558 std::valarray<double>(0.5, 1),
1561 std::valarray< std::valarray<double> >(
1562 std::valarray<double>(1.0, 1),
1569 std::valarray<double> Lc_coef(1.0, 2);
1570 Lc_coef[1]=-1.0/6.0;
1571 expected_real_quantities[
SEMIMAJOR] = &nan_func;
1573 expected_real_quantities[CONV_INCLINATION] = &zero_func;
1574 expected_real_quantities[RAD_INCLINATION] = &zero_func;
1575 expected_real_quantities[CONV_PERIAPSIS] = &zero_func;
1576 expected_real_quantities[RAD_PERIAPSIS] = &zero_func;
1577 expected_real_quantities[CONV_ANGMOM] =
1581 expected_real_quantities[RAD_ANGMOM] =
1583 std::valarray<double>(1.0/6.0, 2),
1587 initial_Lrad = (TSTART / 2.0 + 1.0) / 6.0;
1593 expected_real_quantities,
1599 delete expected_real_quantities[CONV_ANGMOM];
1600 delete expected_real_quantities[RAD_ANGMOM];
1602 TEST_ASSERT_MSG(
false, (std::string(
"Unexpected exception thrown: ")
1605 }
catch (std::exception &ex) {
1606 TEST_ASSERT_MSG(
false, (std::string(
"Unexpected exception thrown: ")
1608 ex.what()).c_str());
1612 void test_OrbitSolver::test_no_planet_evolution()
1615 const double rt2 = std::sqrt(2.0);
1618 *stellar_evol = StellarEvolution::make_no_evolution();
1619 double initial_Lstar[] = {0.0, 0.0};
1621 std::vector<const Core::OneArgumentDiffFunction *>
1622 expected_real_quantities(NUM_REAL_QUANTITIES - 1);
1623 expected_real_quantities[CONV_ANGMOM] = &zero_func;
1624 expected_real_quantities[RAD_ANGMOM] = &zero_func;
1626 unsat_wind_mode.
add_break(TSTART,
false);
1634 expected_real_quantities,
1637 delete stellar_evol;
1638 stellar_evol = StellarEvolution::make_linear_I_evolution();
1640 initial_Lstar[0] = 1.0;
1641 expected_real_quantities[CONV_ANGMOM] = &one_func;
1647 expected_real_quantities,
1651 initial_Lstar[0] = 0.5 * (1.0 + std::exp(-TSTART));
1652 initial_Lstar[1] = 0.5 * (1.0 - std::exp(-TSTART));
1655 std::valarray<double>(0.5, 1),
1674 expected_real_quantities,
1677 delete expected_real_quantities[CONV_ANGMOM];
1678 delete expected_real_quantities[RAD_ANGMOM];
1680 initial_Lstar[0] = 1.0/(1.0+TSTART);
1681 initial_Lstar[1] = 1.0;
1683 double wind_sat_age = std::pow(2.0, 0.25) - 1;
1684 std::valarray<double> late_denom_coef(3);
1685 late_denom_coef[0] = 2.0 * rt2 - 2.0;
1686 late_denom_coef[1] = 4.0 * rt2;
1687 late_denom_coef[2] = 2.0 * rt2;
1689 one_func_early(std::valarray<double>(1.0, 1),
1690 TSTART, wind_sat_age),
1691 one_plus_t(std::valarray<double>(1.0, 2), TSTART,
MAX_AGE),
1692 late_denom2(late_denom_coef, wind_sat_age,
MAX_AGE);
1695 late_solution(&one_plus_t, &late_denom);
1697 full_solution.
add_piece(&early_solution);
1698 full_solution.
add_piece(&late_solution);
1700 expected_real_quantities[CONV_ANGMOM] = &full_solution;
1701 expected_real_quantities[RAD_ANGMOM] = &one_func;
1703 changing_wind_mode.
add_break(TSTART,
true);
1704 changing_wind_mode.
add_break(wind_sat_age,
false);
1711 expected_real_quantities,
1712 changing_wind_mode);
1714 double b1 = (std::sqrt(2) - 1) / (2.0 * rt2),
1715 b2 = (std::sqrt(2) + 1) / (2.0 * rt2);
1716 initial_Lstar[0] = (b1 * std::exp(-TSTART / (2.0 + rt2))
1718 b2 * std::exp(-TSTART / (2.0 - rt2)));
1719 initial_Lstar[1] = (
1720 0.5 / rt2 * std::exp(-1.0 / (2.0 + rt2) * (TSTART))
1722 0.5 / rt2 * std::exp(-1.0 / (2.0 - rt2) * (TSTART))
1726 Lc1(&zero_func, b1, -1.0 / (2.0 + rt2)),
1727 Lc2(&zero_func, b2, -1.0 / (2.0 - rt2)),
1728 Lr1(&zero_func, 0.5 / rt2, -1.0 / (2.0 + rt2)),
1729 Lr2(&zero_func, -0.5 / rt2, -1.0 / (2.0 - rt2));
1731 expected_real_quantities[CONV_ANGMOM] =
new FuncPlusFunc(&Lc1,
1733 expected_real_quantities[RAD_ANGMOM] =
new FuncPlusFunc(&Lr1,
1735 delete stellar_evol;
1736 stellar_evol = StellarEvolution::make_no_evolution();
1742 expected_real_quantities,
1745 delete expected_real_quantities[CONV_ANGMOM];
1746 delete expected_real_quantities[RAD_ANGMOM];
1748 delete stellar_evol;
1750 TEST_ASSERT_MSG(
false, (std::string(
"Unexpected exception thrown: ")+
1752 }
catch (std::exception &ex) {
1753 TEST_ASSERT_MSG(
false, (std::string(
"Unexpected exception thrown: ")+
1754 ex.what()).c_str());
1758 void test_OrbitSolver::test_unlocked_evolution()
1762 binary_mode.
add_break(TSTART, Core::BINARY);
1764 unsat_wind_mode.
add_break(TSTART,
false);
1768 *no_evol = StellarEvolution::make_no_evolution(1.0);
1770 const double mplanet = 100;
1771 double lag = 1e-8 / mplanet;
1773 std::vector<const Core::OneArgumentDiffFunction *>
1786 double initial_a = (
1790 std::valarray<double> initial_L(3);
1791 initial_L[0] = (*expected_real_quantities[CONV_ANGMOM])(
1807 expected_real_quantities,
1816 expected_real_quantities =
1823 initial_a = (*expected_real_quantities[
SEMIMAJOR])(TSTART);
1824 initial_L[0] = (*expected_real_quantities[CONV_ANGMOM])(TSTART);
1836 expected_real_quantities,
1848 std::vector<double>(),
1849 std::vector<double>(),
1850 std::vector<double>(1, 0.0),
1851 std::vector<double>(1, 0.0),
1860 TEST_ASSERT_MSG(
false, (std::string(
"Unexpected exception thrown: ")
1863 }
catch (std::exception &ex) {
1864 TEST_ASSERT_MSG(
false, (std::string(
"Unexpected exception thrown: ")
1866 ex.what()).c_str());
1876 double *dbl_par =
static_cast<double *
>(params);
1877 double alpha = dbl_par[0],
1883 0.1 * alpha * std::pow(a, 5)
1885 0.5 * beta * std::pow(a, 3)
1899 double *dbl_par =
static_cast<double *
>(params);
1900 double alpha = dbl_par[0],
1908 1.5 * beta * std::log(a)
1923 double *dbl_par =
static_cast<double *
>(params);
1924 double alpha = dbl_par[0],
1926 return 0.5 * alpha * std::pow(a, 4) - 1.5 * beta * std::pow(a, 2);
1936 double *dbl_par =
static_cast<double *
>(params);
1937 double alpha = dbl_par[0],
1939 return alpha * a / 2.0 - 1.5 * beta / a;
1949 double *dbl_par =
static_cast<double *
>(params);
1950 double alpha = dbl_par[0],
1956 0.1 * alpha * std::pow(a, 5)
1958 0.5 * beta * std::pow(a, 3)
1964 *df = (0.5 * alpha * std::pow(a, 4)
1966 1.5 * beta * std::pow(a, 2));
1976 double *dbl_par =
static_cast<double *
>(params);
1977 double alpha = dbl_par[0],
1985 1.5 * beta * std::log(a)
1991 *df = alpha * a / 2.0 - 1.5 * beta / a;
1994 void test_OrbitSolver::test_locked_evolution()
1998 expected_mode.
add_break(TSTART, Core::BINARY);
2000 expected_wind_mode.
add_break(TSTART,
false);
2001 const double Ic = 0.001, Kwind = 1e-3, Kwind_s = 1;
2003 no_evol = StellarEvolution::make_no_evolution(1.0, Ic);
2057 Kwind_s * wsat_s * wsat_s *
2072 int_const = (Lscale / 10.0 * std::pow(a1, 5)
2074 beta / 2.0 * std::pow(a1, 3)
2077 int_const_s = (Lscale / 4.0 * std::pow(a1, 2)
2079 3.0 * beta / 2.0 * std::log(a1)
2138 std::valarray<double> a_transform_coef(0.0, 6),
2141 a_transform_coef[5] = Lscale / 10.0;
2142 a_transform_coef[3] = -beta / 2.0;
2143 t_coef[0] = int_const;
2145 t_coef_s[0] = int_const_s;
2146 t_coef_s[1] = -kappa_s;
2147 std::valarray<double> Lconv_term1_coef(0.0, 2),
2148 Lconv_term2_coef(0.0, 3),
2149 identity_coef(0.0, 2),
2150 a_term1_coef_s(0.0, 3),
2151 Lconv_term1_coef_s(0.0, 2),
2152 Lc_beta_coef_s(0.0, 2);
2153 Lconv_term1_coef[1] = 1.0 / beta * std::pow(10.0 / Lscale,
2155 Lconv_term2_coef[2] = -2.0 / std::pow(beta, 3);
2156 identity_coef[1] = 1;
2157 a_term1_coef_s[2] = Lscale / 4.0;
2158 Lconv_term1_coef_s[1] = 1.0 / beta * std::pow(4.0 / Lscale,
2160 Lc_beta_coef_s[1] = 1.0 / beta;
2163 a_transform(a_transform_coef, 0.0, Core::Inf),
2164 a_transform1_s(a_term1_coef_s, 0.0, Core::Inf),
2165 transformed_a_evol(t_coef, TSTART, 1.0),
2166 transformed_a_evol_s(t_coef_s, TSTART, 1.0),
2167 Lconv_term1_poly(Lconv_term1_coef, 0.0, Core::Inf),
2168 Lconv_term2_poly(Lconv_term2_coef, 0.0, Core::Inf),
2169 Lconv_term1_poly_s(Lconv_term1_coef_s, 0.0, Core::Inf),
2170 Lc_beta_s(Lc_beta_coef_s, 0.0, Core::Inf),
2171 identity(identity_coef, 0.0, Core::Inf);
2173 L_transform2(&Lconv_term2_poly, -1.0),
2174 L_transform1_s(&Lconv_term1_poly_s, -4.0 / 3.0);
2176 log_Lc_beta_s(&Lc_beta_s);
2178 L_transform2_s(&log_Lc_beta_s, beta);
2179 FuncPlusFunc L_transform(&L_transform1, &L_transform2),
2180 a_transform_s(&a_transform1_s, &a_transform2_s),
2181 L_transform_s(&L_transform1_s, &L_transform2_s);
2183 std::valarray<double> initial_orbit(2);
2185 initial_orbit[0]=astart;
2186 initial_orbit[1]=0.0;
2187 std::cout.precision(16);
2188 std::cout.setf(std::ios_base::scientific);
2189 Star star_not_saturated_wind_no_coupling(1.0, 0.0, Kwind, wsat, Inf,
2190 0.0, 0.0, 0.0, no_evol);
2191 Planet planet1(&star_not_saturated_wind_no_coupling, 1.0, 1.0, 1.0);
2192 StellarSystem system1(&star_not_saturated_wind_no_coupling, &planet1);
2194 solver(system1, Inf, 0.0, a0, tstart, LOCKED_TO_PLANET, initial_orbit,
true);
2197 test_solution(to_check, transformed_a_evol, transformed_a_evol,
2198 zero_func, tstart, 1.0, expected_mode);
2200 initial_orbit[0]=astart_s;
2201 initial_orbit[1]=0.0;
2202 Star star_saturated_wind_no_coupling(1.0, 0.0, Kwind_s, wsat_s, Inf,
2203 0.0, 0.0, 0.0, no_evol);
2204 Planet planet2(&star_saturated_wind_no_coupling, 1.0, 1.0, 1.0);
2205 StellarSystem system2(&star_saturated_wind_no_coupling, &planet2);
2206 solver(system2, Inf, 0.0, a0_s, tstart, LOCKED_TO_PLANET,
2207 initial_orbit,
true);
2211 test_solution(to_check_s, transformed_a_evol_s, transformed_a_evol_s,
2212 zero_func, tstart, 1.0, expected_mode);
2216 TEST_ASSERT_MSG(
false, (std::string(
"Unexpected exception thrown: ")
2219 }
catch (std::exception &ex) {
2220 TEST_ASSERT_MSG(
false, (std::string(
"Unexpected exception thrown: ")
2222 ex.what()).c_str());
2226 void test_OrbitSolver::test_disklocked_to_locked_to_noplanet()
2229 const double Ic = 0.001,
2234 no_evol = StellarEvolution::make_no_evolution(1.0, Ic);
2236 double afinal = 1.75,
2288 int_const = (Lscale / 10.0 * std::pow(afinal, 5)
2290 beta / 2.0 * std::pow(afinal, 3)
2293 double solver_params[]={Lscale, beta, kappa, int_const, tdisk};
2294 double ainitial = solve(2.0 * afinal,
2300 static_cast<void*>(solver_params)),
2318 1e7 * std::numeric_limits<double>::epsilon()
2334 ainitial * (1.0 - 1e-14),
2346 ainitial * (1.0 - 1e-14),
2361 Core::LOCKED_SURFACE_SPIN);
2365 tdestr = ((beta / 2.0 * std::pow(adestr, 3)
2369 Lscale / 10.0 * std::pow(adestr, 5)) / kappa),
2370 Lc_at_destr = (beta / std::pow(adestr, 1.5)
2372 Lscale * std::sqrt(adestr));
2375 std::valarray<double> a_transform_coef(0.0, 6), t_coef(2);
2376 a_transform_coef[5] = Lscale / 10.0;
2377 a_transform_coef[3] = -beta / 2.0;
2378 t_coef[0] = int_const;
2380 std::valarray<double> Lconv_term1_coef(0.0, 2),
2381 Lconv_term2_coef(0.0, 3),
2382 identity_coef(0.0, 2),
2383 noplanet_Lconv_m2_coef(2);
2384 Lconv_term1_coef[1] = 1.0 / beta * std::pow(10.0 / Lscale, 0.3);
2385 Lconv_term2_coef[2] = -2.0 / std::pow(beta, 3);
2386 noplanet_Lconv_m2_coef[0] = (
2387 std::pow(Lc_at_destr, -2)
2389 2.0 * Kwind * tdestr / std::pow(Ic, 3)
2391 noplanet_Lconv_m2_coef[1] = 2.0 * Kwind / std::pow(Ic, 3);
2392 identity_coef[1] = 1;
2394 identity(identity_coef, -Core::Inf, Core::Inf),
2395 disk_nan_evol(std::valarray<double>(Core::NaN, 2),
2398 locked_a_transform(a_transform_coef, -Core::Inf, Core::Inf),
2399 locked_aLconv_evol(t_coef, tdisk, tdestr),
2400 locked_e_evol(std::valarray<double>(), tdisk, tdestr),
2401 noplanet_nan_evol(std::valarray<double>(Core::NaN, 2),
2404 disk_Lconv_evol(std::valarray<double>(wdisk * Ic, 1),
2407 noplanet_Lconv_m2_evol(noplanet_Lconv_m2_coef, tdestr, tfinal),
2408 Lconv_term1_poly(Lconv_term1_coef, -Core::Inf, Core::Inf),
2409 Lconv_term2_poly(Lconv_term2_coef, -Core::Inf, Core::Inf),
2410 Lrad_evol(std::valarray<double>(), TSTART, tfinal);
2412 L_transform2(&Lconv_term2_poly, -1.0),
2413 noplanet_Lconv_evol(&noplanet_Lconv_m2_evol, -0.5);
2415 FuncPlusFunc locked_Lconv_transform(&L_transform1, &L_transform2);
2424 Lconv_evol.
add_piece(&locked_aLconv_evol);
2425 Lconv_evol.
add_piece(&noplanet_Lconv_evol);
2427 std::vector< const Core::OneArgumentDiffFunction * >
2428 transformations(NUM_REAL_QUANTITIES - 1, &identity);
2430 transformations[
SEMIMAJOR] = &locked_a_transform;
2431 transformations[CONV_ANGMOM] = &locked_Lconv_transform;
2434 transformations[CONV_ANGMOM] = &identity;
2438 expected_evol_mode.
add_break(TSTART, Core::LOCKED_SURFACE_SPIN);
2439 expected_evol_mode.
add_break(tdisk, Core::BINARY);
2440 expected_evol_mode.
add_break(tdestr, Core::SINGLE);
2443 expected_wind_mode.
add_break(TSTART,
false);
2448 (tfinal - __system->age()) / 10000.0,
2449 std::list<double>());
2451 std::vector< const std::list<double> * >
2453 const std::vector< const std::list<double> * > &
2454 transformed_evolution = to_check(tabulated_evolution);
2456 std::vector<const Core::OneArgumentDiffFunction *>
2457 expected_real_quantities(NUM_REAL_QUANTITIES - 1);
2458 expected_real_quantities[
SEMIMAJOR] = &a_evol;
2460 expected_real_quantities[CONV_INCLINATION] = &zero_func;
2461 expected_real_quantities[RAD_INCLINATION] = &zero_func;
2462 expected_real_quantities[CONV_PERIAPSIS] = &zero_func;
2463 expected_real_quantities[RAD_PERIAPSIS] = &zero_func;
2464 expected_real_quantities[CONV_ANGMOM] = &Lconv_evol;
2465 expected_real_quantities[RAD_ANGMOM] = &Lrad_evol;
2468 expected_real_quantities,
2476 Star star_not_saturated_wind_no_coupling(
2486 Planet planet1(&star_not_saturated_wind_no_coupling, 1.0, 1.0, 1.0);
2487 StellarSystem system1(&star_not_saturated_wind_no_coupling, &planet1);
2516 TEST_ASSERT_MSG(
false, (std::string(
"Unexpected exception thrown: ")
2519 }
catch (std::exception &ex) {
2520 TEST_ASSERT_MSG(
false, (std::string(
"Unexpected exception thrown: ")
2522 ex.what()).c_str());
2527 void test_OrbitSolver::test_disklocked_to_fast_to_noplanet()
2530 const double TDISK = 1,
2553 no_evol = StellarEvolution::make_no_evolution(1.0, I_CONV);
2582 Core::AstroConst::solar_mass))
2590 __star->
mass() * Core::AstroConst::solar_mass
2601 double a6p5_offset = (std::pow(adestr, 6.5)
2603 6.5 * alpha * TDESTR),
2604 a_formation = std::pow(a6p5_offset + 6.5 * alpha * TDISK,
2613 expected_mode.
add_break(TSTART, Core::LOCKED_SURFACE_SPIN);
2614 expected_mode.
add_break(TDISK, Core::BINARY);
2615 expected_mode.
add_break(TDESTR, Core::SINGLE);
2618 unsat_wind_mode.
add_break(TSTART,
false);
2620 std::valarray<double> a6p5_poly_coef(2);
2621 a6p5_poly_coef[0] = a6p5_offset;
2622 a6p5_poly_coef[1] = 6.5 * alpha;
2624 a6p5_evol(a6p5_poly_coef, TDISK, TDESTR),
2625 Lconv_disk(std::valarray<double>(I_CONV*
WDISK, 1),
2629 std::valarray<double>(
2630 -L_SCALE * std::sqrt(a_formation) + I_CONV * WDISK,
2636 nan_disk(std::valarray<double>(Core::NaN, 2), TSTART, TDISK),
2637 nan_noplanet(std::valarray<double>(Core::NaN, 2),
2640 e_fast(std::valarray<double>(0.0, 1),
2643 Lrad_evol(std::valarray<double>(), TSTART,
MAX_AGE);
2645 sqrta_evol(&a6p5_evol, 1.0 / 13.0);
2648 I_CONV * WDISK / L_SCALE - std::sqrt(a_formation),
2653 std::vector<const Core::OneArgumentDiffFunction *>
2654 expected_real_quantities(NUM_REAL_QUANTITIES - 1);
2666 conv_angmom_evol.
add_piece(&Lconv_disk);
2667 conv_angmom_evol.
add_piece(&Lconv_fast);
2672 expected_real_quantities[
SEMIMAJOR] = &a_evol;
2674 expected_real_quantities[CONV_INCLINATION] = &zero_func;
2675 expected_real_quantities[RAD_INCLINATION] = &zero_func;
2676 expected_real_quantities[CONV_PERIAPSIS] = &zero_func;
2677 expected_real_quantities[RAD_PERIAPSIS] = &zero_func;
2678 expected_real_quantities[RAD_ANGMOM] = &zero_func;
2679 expected_real_quantities[CONV_ANGMOM] = &conv_angmom_evol;
2680 expected_real_quantities[RAD_ANGMOM] = &zero_func;
2683 expected_real_quantities,
2691 TEST_ASSERT_MSG(
false, (std::string(
"Unexpected exception thrown: ")+
2693 }
catch (std::exception &ex) {
2694 TEST_ASSERT_MSG(
false, (std::string(
"Unexpected exception thrown: ")+
2695 ex.what()).c_str());
2699 void test_OrbitSolver::test_disklocked_to_fast_to_locked()
2702 const double lgQ = 8,
2708 std::vector<const Core::OneArgumentDiffFunction *>
2709 expected_real_quantities
2711 calculate_expected_disklocked_to_fast_to_locked(
2719 double wsync = Core::orbital_angular_velocity(1.0,
2722 Lconv_sync = (*expected_real_quantities[CONV_ANGMOM])(
2723 (tsync + tend) / 2.0
2725 Iconv = Lconv_sync / wsync,
2726 Ldisk = (*expected_real_quantities[CONV_ANGMOM])(
2727 (TSTART + tdisk) / 2.0
2729 wdisk = Ldisk / Iconv,
2730 a_formation = (*expected_real_quantities[
SEMIMAJOR])(tdisk),
2737 no_evol = StellarEvolution::make_no_evolution(1.0, Iconv);
2748 expected_evol_mode.
add_break(TSTART, Core::LOCKED_SURFACE_SPIN);
2749 expected_evol_mode.
add_break(tdisk, Core::BINARY);
2752 expected_wind_mode.
add_break(TSTART,
false);
2758 (
__star ? &zero : &Ldisk),
2766 std::list<double>(1, tsync));
2769 expected_real_quantities,
2772 (
__star ? TSTART : tdisk),
2780 std::vector<double>(),
2781 std::vector<double>(),
2782 std::vector<double>(1, 0.0),
2783 std::vector<double>(1, 0.0),
2795 std::string(
"Unexpected exception thrown: ")
2799 }
catch (std::exception &ex) {
2803 std::string(
"Unexpected exception thrown: ")
2811 void test_OrbitSolver::test_disklocked_to_locked_to_fast()
2851 wdisk = beta / std::pow(a0, 1.5),
2853 (std::pow(abreak, 6.5) - std::pow(adeath, 6.5))
2889 (std::pow(a0, 5) - std::pow(abreak, 5))
2891 std::pow(abreak, 3.5)
2896 5.0 * gamma * abreak * abreak
2901 (std::pow(a0, 3) - std::pow(abreak, 3))
2903 std::pow(abreak, 3.5) * 6.5
2914 (std::pow(a0, 5) - std::pow(abreak, 5)) * alphaL / 10.0
2916 (std::pow(a0, 3) - std::pow(abreak, 3)) * beta * Ic / 2.0
2936 locked_a_int_const = (alphaL * std::pow(a0, 5) / 10.0
2938 beta * Ic * std::pow(a0, 3) / 2.0
2943 no_evol = StellarEvolution::make_no_evolution(1.0, Ic);
2968 expected_evol_mode.
add_break(TSTART, Core::LOCKED_SURFACE_SPIN);
2969 expected_evol_mode.
add_break(tdisk, Core::BINARY);
2970 expected_evol_mode.
add_break(tdeath, Core::SINGLE);
2973 expected_wind_mode.
add_break(TSTART,
false);
2975 std::valarray<double> a_locked_transform_coef(0.0, 6),
2976 a_locked_evol_coef(2),
2977 identity_coef(0.0, 2),
2978 a6p5_fast_evol_coef(2),
2979 Lconv_locked_term1_coef(0.0, 2),
2980 Lconv_locked_term2_coef(0.0, 3);
2981 a_locked_transform_coef[5] = alphaL / 10.0;
2982 a_locked_transform_coef[3] = -beta * Ic / 2.0;
2983 a_locked_evol_coef[0] = locked_a_int_const;
2984 a_locked_evol_coef[1] = -kappa;
2985 identity_coef[1] = 1.0;
2986 a6p5_fast_evol_coef[0] = gamma * tbreak + std::pow(abreak, 6.5);
2987 a6p5_fast_evol_coef[1] = -gamma;
2988 Lconv_locked_term1_coef[1] = (1.0
2992 std::pow(10.0 / alphaL, 3.0 / 10.0));
2993 Lconv_locked_term2_coef[2] = -2.0 / std::pow(beta * Ic, 3);
2996 identity(identity_coef, -Core::Inf, Core::Inf),
2997 a_disk_transform = identity,
2998 nan_disk_evol(std::valarray<double>(Core::NaN, 2),
3001 a_locked_transform(a_locked_transform_coef,
3004 a_locked_evol(a_locked_evol_coef, tdisk, tbreak),
3005 a_fast_transform = identity,
3006 a6p5_fast_evol(a6p5_fast_evol_coef, tbreak, tdeath),
3007 a_noplanet_transform = identity,
3008 nan_noplanet_evol(std::valarray<double>(Core::NaN, 2),
3012 Lconv_disk_transform = identity,
3013 Lconv_disk_evol(std::valarray<double>(wdisk * Ic, 1),
3016 Lconv_locked_term1_poly(Lconv_locked_term1_coef,
3019 Lconv_locked_term2_poly(Lconv_locked_term2_coef,
3022 Lconv_locked_evol = a_locked_evol,
3023 Lconv_fast_transform(std::valarray<double>(Core::NaN, 2),
3026 Lconv_fast_evol(std::valarray<double>(Core::NaN, 2),
3029 Lconv_noplanet_transform(std::valarray<double>(Core::NaN, 2),
3032 Lconv_noplanet_evol(std::valarray<double>(Core::NaN, 2),
3035 Lrad_transform = identity,
3036 Lrad_evol(std::valarray<double>(), TSTART, tend),
3037 zero_e(std::valarray<double>(), tdisk, tdeath);
3040 a_fast_evol(&a6p5_fast_evol, 1.0 / 6.5),
3041 Lconv_locked_transform1(&Lconv_locked_term1_poly,
3043 Lconv_locked_transform2(&Lconv_locked_term2_poly, -1.0);
3045 FuncPlusFunc Lconv_locked_transform(&Lconv_locked_transform1,
3046 &Lconv_locked_transform2);
3060 Lconv_evol.
add_piece(&Lconv_locked_evol);
3062 Lconv_evol.
add_piece(&Lconv_noplanet_evol);
3064 std::vector< const Core::OneArgumentDiffFunction * >
3065 transformations(NUM_REAL_QUANTITIES - 1, &identity);
3068 transformations[
SEMIMAJOR] = &a_disk_transform;
3069 transformations[CONV_ANGMOM] = &Lconv_disk_transform;
3072 transformations[
SEMIMAJOR] = &a_locked_transform;
3073 transformations[CONV_ANGMOM] = &Lconv_locked_transform;
3076 transformations[
SEMIMAJOR] = &a_fast_transform;
3077 transformations[CONV_ANGMOM] = &Lconv_fast_transform;
3080 transformations[
SEMIMAJOR] = &a_fast_transform;
3081 transformations[CONV_ANGMOM] = &Lconv_fast_transform;
3084 transformations[
SEMIMAJOR] = &a_noplanet_transform;
3085 transformations[CONV_ANGMOM] = &Lconv_noplanet_transform;
3088 std::vector<const Core::OneArgumentDiffFunction *>
3089 expected_real_quantities(NUM_REAL_QUANTITIES - 1);
3091 std::vector< const std::list<double> * >
3094 const std::vector< const std::list<double> * > &
3095 transformed_evolution = to_check(tabulated_evolution);
3097 expected_real_quantities[
SEMIMAJOR] = &a_evol;
3099 expected_real_quantities[CONV_INCLINATION] = &zero_func;
3100 expected_real_quantities[RAD_INCLINATION] = &zero_func;
3101 expected_real_quantities[CONV_PERIAPSIS] = &zero_func;
3102 expected_real_quantities[RAD_PERIAPSIS] = &zero_func;
3103 expected_real_quantities[CONV_ANGMOM] = &Lconv_evol;
3104 expected_real_quantities[RAD_ANGMOM] = &zero_func;
3107 expected_real_quantities,
3117 std::string(
"Unexpected exception thrown: ")
3122 }
catch (std::exception &ex) {
3126 std::string(
"Unexpected exception thrown: ")
3135 void test_OrbitSolver::test_polar_1_0_evolution()
3138 no_evol = StellarEvolution::make_no_evolution();
3140 const double TDISK = 0.1,
3143 double initial_L = 1.0;
3144 std::vector<const Core::OneArgumentDiffFunction *>
3145 expected_real_quantities = calculate_expected_polar_1_0(
3151 expected_evol_mode.
add_break(TSTART, Core::LOCKED_SURFACE_SPIN);
3152 expected_evol_mode.
add_break(TDISK, Core::BINARY);
3155 expected_wind_mode.
add_break(TSTART,
false);
3157 double semimajor = (*expected_real_quantities[
SEMIMAJOR])(
3178 expected_real_quantities,
3181 (
__star ? TSTART : TDISK),
3207 void test_OrbitSolver::test_polar_2_0_evolution()
3210 no_evol = StellarEvolution::make_no_evolution();
3212 const double TDISK = 0.1,
3217 double lconv_decay_rate, semimajor, initial_L = 1.0;
3219 std::vector<const Core::OneArgumentDiffFunction *>
3220 expected_real_quantities = calculate_expected_polar_2_0(TDISK,
3228 std::valarray<double> identity_coef(0.0, 2);
3229 identity_coef[1] = 1.0;
3231 identity(identity_coef, -Core::Inf, Core::Inf),
3232 one_func(std::valarray<double>(1.0, 1), -Core::Inf, Core::Inf);
3244 2.0 * (WSTAR - lconv_decay_rate *
MAX_AGE),
3245 2.0 * (WSTAR + lconv_decay_rate * MAX_AGE),
3257 std::vector< const Core::OneArgumentDiffFunction * >
3258 transformations(NUM_REAL_QUANTITIES - 1, &identity);
3259 transformations[CONV_INCLINATION] = &one_plus_cos_transform;
3260 transformations[RAD_INCLINATION] = &one_plus_cos_transform;
3263 std::vector< const std::list<double> * >
3265 const std::vector< const std::list<double> * > &
3266 transformed_evolution = to_check(tabulated_evolution);
3269 expected_evol_mode.
add_break(TSTART, Core::LOCKED_SURFACE_SPIN);
3270 expected_evol_mode.
add_break(TDISK, Core::BINARY);
3273 expected_wind_mode.
add_break(TSTART,
false);
3276 expected_real_quantities,
3279 (
__star ? TSTART : TDISK),
3292 2.0 * (WSTAR - lconv_decay_rate * MAX_AGE),
3293 2.0 * (WSTAR + lconv_decay_rate * MAX_AGE),
3304 void test_OrbitSolver::test_oblique_1_0_evolution()
3307 no_evol = StellarEvolution::make_no_evolution();
3309 const double PHASE_LAG = 0.1,
3312 INITIAL_INC = 0.25 * M_PI,
3313 INITIAL_WSTAR = 0.01;
3315 double initial_angmom = 1.0,
3318 std::vector<const Core::OneArgumentDiffFunction *>
3319 expected_real_quantities = calculate_expected_oblique_m_0(
3329 double wstar_tolerance = 0.01 * (INITIAL_WSTAR - min_wstar),
3330 semimajor = (*expected_real_quantities[
SEMIMAJOR])(
3335 expected_evol_mode.
add_break(TSTART, Core::LOCKED_SURFACE_SPIN);
3339 expected_wind_mode.
add_break(TSTART,
false);
3346 min_wstar - wstar_tolerance,
3347 INITIAL_WSTAR + wstar_tolerance,
3348 0.1 * INITIAL_WSTAR,
3360 expected_real_quantities,
3376 min_wstar - wstar_tolerance,
3377 INITIAL_WSTAR + wstar_tolerance,
3378 0.1 * INITIAL_WSTAR,
3382 initial_angmom = INITIAL_WSTAR;
3388 void test_OrbitSolver::test_oblique_2_0_evolution()
3391 no_evol = StellarEvolution::make_no_evolution();
3393 const double PHASE_LAG = 0.1,
3396 INITIAL_INC = 0.25 * M_PI,
3397 INITIAL_WSTAR = 0.01;
3399 double initial_angmom = 1.0,
3402 std::vector<const Core::OneArgumentDiffFunction *>
3403 expected_real_quantities = calculate_expected_oblique_m_0(
3413 double wstar_tolerance = 0.01 * (INITIAL_WSTAR - min_wstar),
3414 semimajor = (*expected_real_quantities[
SEMIMAJOR])(
3419 expected_evol_mode.
add_break(TSTART, Core::LOCKED_SURFACE_SPIN);
3423 expected_wind_mode.
add_break(TSTART,
false);
3430 2.0 * min_wstar - wstar_tolerance,
3431 2.0 * INITIAL_WSTAR + wstar_tolerance,
3432 0.1 * INITIAL_WSTAR,
3444 expected_real_quantities,
3459 2.0 * min_wstar - wstar_tolerance,
3460 2.0 * INITIAL_WSTAR + wstar_tolerance,
3461 0.1 * INITIAL_WSTAR,
3465 initial_angmom = INITIAL_WSTAR;
3474 void test_OrbitSolver::setup()
3483 void test_OrbitSolver::tear_down()
3486 std::cout <<
"Deleting star" << std::endl;
3491 std::cout <<
"Deleting primary planet" << std::endl;
3496 std::cout <<
"Deleting system" << std::endl;
3501 std::cout <<
"Deleting solver" << std::endl;
3506 std::vector< const Core::OneArgumentDiffFunction* >::iterator
3511 std::cout <<
"Deleting function" << std::endl;
3512 delete *temp_func_i;
3517 test_OrbitSolver::test_OrbitSolver() :
3524 TEST_ADD(test_OrbitSolver::test_disk_locked_no_stellar_evolution);
3525 TEST_ADD(test_OrbitSolver::test_disk_locked_with_stellar_evolution);
3526 TEST_ADD(test_OrbitSolver::test_no_planet_evolution);
3527 TEST_ADD(test_OrbitSolver::test_unlocked_evolution);
3528 TEST_ADD(test_OrbitSolver::test_disklocked_to_fast_to_noplanet);
3529 TEST_ADD(test_OrbitSolver::test_polar_1_0_evolution);
3530 TEST_ADD(test_OrbitSolver::test_polar_2_0_evolution);
3531 TEST_ADD(test_OrbitSolver::test_oblique_1_0_evolution);
3532 TEST_ADD(test_OrbitSolver::test_disklocked_to_fast_to_locked);
3533 TEST_ADD(test_OrbitSolver::test_disklocked_to_locked_to_fast);
3534 TEST_ADD(test_OrbitSolver::test_disklocked_to_locked_to_noplanet);
3535 TEST_ADD(test_OrbitSolver::test_locked_evolution);
Implements a StellarEvolution based on polynomial evolution quantities.
Star::InterpolatedEvolutionStar * __star
The star used in the current test (NULL if primary is planet).
const double MIN_AGE
Most tests start at this age in Gyr.
Age in Myr when disk dissipates.
const std::list< double > & eccentricity_evolution() const
The tabulated evolution of the eccentricity so far.
double locked_sat_eq(double a, void *params)
The equation that should be solved in order to get the semimamjor axis at a given time for the locked...
Declares the test suite that exercises the OrbitSolver class and some other clasess necessary to acco...
const std::string & get_message() const
Details about what caused the error.
The orbital periapsis in the reference frame of the stellar radiative zone in radians.
void detect_saturation()
Sets the saturation based on the currently configured spin frequency.
The base class of all exceptions.
const std::list< Core::EvolModeType > & mode_evolution() const
The tabulated evolution modes so far.
The orbital frequency in rad/day.
A function scaled by some constant.
std::ostream & operator<<(std::ostream &os, const ZoneEvolutionQuantities &evol_var)
More civilized output for EvolVarType variables.
A base class for any body contributing to tidal dissipation.
void locked_sat_eq_deriv(double a, void *params, double *f, double *df)
The equation and its derivative that should be solved in order to get the semimamjor axis at a given ...
virtual double minimum_separation(bool deriv=false) const
Smallest semimajor axis at which the secondary can survive for the latest system configuration.
A class representing a once differentiable function of a single argument.
SEMIMAJOR
The derivative w.r.t. the semimajor axis in AU.
Single zone non-evolving planets with huge dissipation, so they always remain locked to the disk...
void test_no_planet_scenario(const StellarEvolution::Interpolator &stellar_evol, double *initial_Lstar, double windK, double wind_sat_freq, double core_env_coupling_time, std::vector< const Core::OneArgumentDiffFunction *> &expected_evolution, const ExpectedEvolutionMode< bool > &expected_wind_mode, double max_age=MAX_AGE, bool debug_mode=false)
Test a planet-less scenario computed in 3 different ways: 1) withou a planet 2) without dissipation 3...
The angle between the stellar core spin and orbital angular momentum in radians.
const Evolve::DissipatingZone & zone(unsigned zone_index) const
Returns the only zone.
struct LIB_PUBLIC OrbitSolver
Opaque struct to cast to/from Evolve::OrbitSolver.
The angle between the stellar surface spin and orbital angular momentum in radians.
const double jupiter_mass
Mass of Jupiter [kg].
void make_single_component_star(const StellarEvolution::Interpolator &evolution, double wind_strength, double wind_sat_freq, double coupling_timescale, double min_frequency, double max_frequency, double decay_scale, double phase_lag=1.0e-5)
Create __star with constant dissipation in a range, quickly decaying outside of that.
Evolve::DiskBinarySystem * __system
The system being evolved by the current test.
const double MAX_AGE
Most tests end at this age in Gyr.
Orientations of zones of bodies in a binary system.
const std::list< double > & semimajor_evolution() const
The tabulated evolution of the semimajor axis so far.
const std::list< bool > & wind_saturation_evolution() const
The tabulated wind saturation states so far.
const EvolvingStellarCore & core() const
The core of the star.
Planet::Planet * __primary_planet
The primary planet in the current test (NULL if primary is star).
RealEvolutionQuantity
Define identifiers for the quantities whose evolution we check.
struct LIB_PUBLIC DiskBinarySystem
Opaque struct to cast to/from Evolve::DiskBinarySystem.
A class that interpolates among stellar evolution tracks.
Represents the sum of two functions and the derivative.
const double jupiter_radius
Radius of Jupiter [m].
double mass() const
The mass of the body (constant with age).
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.
double lag_from_lgQ(double lgQ)
Converts lg(Q) to a tidal phase lag.
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...
The cosine of a function.
An EvolvingStellar quantity that uses a polynomial instead of interpolating.
The natural logarithm of a function.
Stellar surface spin while disk is present in rad/day.
void set_single_component_dissipation(double min_frequency, double max_frequency, double decay_scale, double phase_lag=1.0e-5)
Set the dissipation of the primary to only a single tidal.
virtual const char * what() const
The type of error.
bool check_diff(double x, double y, double frac_tolerance, double abs_tolerance)
Returns true iff .
void evolve(double wdisk, double tdisk, double initial_a, const double *initial_Lstar, double initial_incl=0.0, double secondary_mass=1.0, double tsecondary=Core::NaN, double max_age=MAX_AGE, double secondary_radius=1.0, double precision=1e-8, double max_step_factor=1e-3, const std::list< double > required_ages=std::list< double >())
Add a planet to the given star and evolve, returning the solver.
double locked_unsat_deriv(double a, void *params)
The derivative of the equation that should be solved in order to get the semimamjor axis at a given t...
ECCENTRICITY
The derivative w.r.t. the eccentricity.
std::vector< const Core::OneArgumentDiffFunction * > calculate_expected_unlocked_evolution(double phase_lag, double secondary_mass, bool decaying=true)
Calculate the predicted evolution for the test_unlocked_evolution() case.
const double solar_mass
Mass of the sun [kg].
const EvolvingStellarEnvelope & envelope() const
The envelope of the star - inmodifiable.
AGE
The derivative w.r.t. age, excluding the dependence through the body's radius and the moments of iner...
The minimum age to start evolution at in Gyr.
Several functions stiched together.
A DissipatingZone where the phase lag is described by a broken powerlaw.
bool near_break(double age) const
Is the given age close to a break (hence ambigous mode).
EvolModeType
The various evolution modes.
void test_solution(const std::vector< const std::list< double > * > &tabulated_real_quantities, std::vector< const Core::OneArgumentDiffFunction *> expected_real_quantities, const ExpectedEvolutionMode< Core::EvolModeType > &expected_evol_mode, const ExpectedEvolutionMode< bool > &expected_wind_mode, double min_age, double max_age, bool debug_mode=false)
Tests the latest evolution calculated by the solver against the given tracks.
const std::list< double > & get_evolution_real(ZoneEvolutionQuantities quantity) const
The tabulated evolution of a real valued quantity so far.
std::vector< const Core::OneArgumentDiffFunction *> __temp_functions
A list of functions allocated during a test to delete at the end.
Angular momentum of the zone.
void locked_unsat_eq_deriv(double a, void *params, double *f, double *df)
The equation and its derivative that should be solved in order to get the semimamjor axis at a given ...
Represents a function of the form offset + scale*exp(rate*x) as well as its derivative.
Solves the system of ODEs describing the evolution of a single planet around a single star...
Evolve::OrbitSolver * __solver
The solver used for the current test.
A function raised to some power.
double locked_unsat_eq(double a, void *params)
The equation that should be solved in order to get the semimamjor axis at a gien time.
The orbital periapsis in the reference frame of the stellar convective zone in radians.
void add_piece(const OneArgumentDiffFunction *piece)
Adds another piece of the function, where it applies is defined by its range.
Star::InterpolatedEvolutionStar * make_const_lag_star(const StellarEvolution::Interpolator &evolution, double wind_strength, double wind_sat_freq, double coupling_timescale, double phase_lag)
Create a star with the given parameters with a constant phase lag.
The ratio of two functions;.
std::vector< const std::list< double > * > get_evolution() const
Return the last calculated evolution.
double locked_sat_deriv(double a, void *params)
The derivative of the equation that should be solved in order to get the semimamjor axis at a gien ti...
void add_break(double age, MODE_TYPE mode)
Add an evolution mode that applies up to the given age.
virtual int configure(bool initialize, double age, double semimajor, double eccentricity, const double *spin_angmom, const double *inclination, const double *periapsis, Core::EvolModeType evolution_mode)
Sets the current state of the system.
Some evolution mode that changes at specified ages.
const std::list< double > & evolution_ages() const
The ages at which evolution has been tabulated so far.
const double G
Gravitational constant in SI.
void setup(const std::vector< double > &tidal_frequency_breaks, const std::vector< double > &spin_frequency_breaks, const std::vector< double > &tidal_frequency_powers, const std::vector< double > &spin_frequency_powers, double reference_phase_lag, double inertial_mode_enhancement=1.0, double inertial_mode_sharpness=10.0)
Seup the zone with the given breaks/powers and inertial mode enhancement. Continuous accress all brea...